Accessify
Python design kit: interfaces, declared exception throws, class members accessibility levels (private and protected methods for humans).
Install / Use
/learn @dmytrostriletskyi/AccessifyREADME
accessify
Getting started
What is accessify
accessify is a Python design kit that provides:
- interfaces,
- declared exceptions throws,
- class members accessibility levels.
that could be combined with each other to make your code slim and this library usage more justified.
<h3 id="getting-started-access-modifiers">Access modifiers</h3>Access level modifiers determine whether other classes can use a particular field or invoke a particular method.
Accessibility levels are presented from the box in the languages like C++, C# and Java.
class Car
{
private string StartEngine()
{
// Code here.
}
}
But Python does not have this in the same way.
We're all consenting adults herethat is the part of thePython philosophythat relies on human factor instead of the interpreter.- There is a
Python conventionthat is to use an underscore prefix for protected and private members, that is a bit ugly. Isn't it? For instance, for the following piece of code that provides class a private member.
class Car:
def __start_engine(self, *args, **kwargs):
pass
- Moreover, private and protected methods could be easily accessed outside the class. This is really a point to postpone the correct design of the system to the backlog, increasing the technical debt.
class Car:
def _start_engine(self, *args, **kwargs):
pass
def __start_engine(self, *args, **kwargs):
pass
car = Car()
car._start_engine()
car._Car__start_engine()
<h3 id="getting-started-interfaces">Interfaces</h3>
An interface is a contract specifying a set of methods and properties which required to be available on any implementing class.
If the class implements an interface, but does not realize its method, corresponding errors should be raised. Interfaces are presented from the box in
the languages like C++, C# and Java.
interface HumanInterface
{
public string EatFood();
}
class Human : HumanInterface
{
public string EatFood()
{
// Code here.
}
}
But Python does not have this in the same way.
- The interface makes checks during the implementation creation, but not actually while execution like abc module in
Python. - The interface requires that implementation's method arguments match with arguments declared in interfaces, abc — not.
- A lot of libraries that provide interfaces are no longer supported.
- A lot of libraries that provide interfaces require you to write a lot of code to use its functionality, this library — not.
How to install
Using pip install the package from the PyPi.
$ pip3 install accessify
Usage
<h3 id="usage-access-modifiers">Access modifiers</h3>Private
- Private members are accessible only within the body of the class.
In this example, the Car class contains a private member named start_engine. As a private member, they cannot be accessed
except by member methods. The private member start_engine is accessed only by way of a public method called run.
from accessify import private
class Car:
@private
def start_engine(self):
return 'Engine sound.'
def run(self):
return self.start_engine()
if __name__ == '__main__':
car = Car()
assert 'Engine sound.' == car.run()
car.start_engine()
The code above will produce the following traceback.
Traceback (most recent call last):
File "examples/access/private.py", line 24, in <module>
car.start_engine()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/accessify/main.py", line 92, in private_wrapper
class_name=instance_class.__name__, method_name=method.__name__,
accessify.errors.InaccessibleDueToItsProtectionLevelException: Car.start_engine() is inaccessible due to its protection level
Test it out using the examples.
Get the example that contains the code above by curl and run it by python3.
$ curl -L https://git.io/fhASP > private.py
$ python3 private.py
- Child classes cannot access parent private members.
In this example, the Car class contains a private member named start_engine. As a private member, they cannot be accessed
from the child classes, Tesla in our case. So overridden method run by Tesla class cannot use the parent's start_engine member.
from accessify import private
class Car:
@private
def start_engine(self):
return 'Engine sound.'
class Tesla(Car):
def run(self):
return self.start_engine()
if __name__ == '__main__':
tesla = Tesla()
tesla.run()
The code above will produce the following traceback.
Traceback (most recent call last):
File "examples/inheritance/private.py", line 23, in <module>
tesla.run()
File "examples/inheritance/private.py", line 18, in run
return self.start_engine()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/accessify/main.py", line 94, in private_wrapper
class_name=class_contain.__name__, method_name=method.__name__,
accessify.errors.InaccessibleDueToItsProtectionLevelException: Car.start_engine() is inaccessible due to its protection level
Test it out using the examples.
Get the example that contains the code above by curl and run it by python3.
$ curl -L https://git.io/fhASX > inheritence_private.py
$ python3 inheritence_private.py
Protected
- A protected member is accessible within its class and by derived class instances.
In this example, the Car class contains a protected member named start_engine. As a protected member, they cannot be accessed
except by member methods. The protected member start_engine is accessed only by way of a public method called run.
from accessify import protected
class Car:
@protected
def start_engine(self):
return 'Engine sound.'
def run(self):
return self.start_engine()
if __name__ == '__main__':
car = Car()
assert 'Engine sound.' == car.run()
car.start_engine()
The code above will produce the following traceback.
Traceback (most recent call last):
File "examples/access/protected.py", line 21, in <module>
car.start_engine()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/accessify/main.py", line 134, in protected_wrapper
class_name=instance_class.__name__, method_name=method.__name__,
accessify.errors.InaccessibleDueToItsProtectionLevelException: Car.start_engine() is inaccessible due to its protection level
Test it out using the examples.
Get the example that contains the code above by curl and run it by python3.
$ curl -L https://git.io/fhASM > protected.py
$ python3 protected.py
- Child classes have access to those protected members.
In this example, the Car class contains a protected member named start_engine. As a protected member, they can be accessed
from the child classes, Tesla in our case. So overridden method run by Tesla class can use the parent's start_engine member.
from accessify import protected
class Car:
@protected
def start_engine(self):
return 'Engine sound.'
class Tesla(Car):
def run(self):
return self.start_engine()
if __name__ == '__main__':
tesla = Tesla()
assert 'Engine sound.' == tesla.run()
The code will work without errors.
Test it out using the [examples](https://github.com/dmytrostriletskyi/accessify/tr
