معرفی شرکت ها


abstracts-0.0.9


Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر
Card image cap
تبلیغات ما

مشتریان به طور فزاینده ای آنلاین هستند. تبلیغات می تواند به آنها کمک کند تا کسب و کار شما را پیدا کنند.

مشاهده بیشتر

توضیحات

Abstract class and interface definitions
ویژگی مقدار
سیستم عامل -
نام فایل abstracts-0.0.9
نام abstracts
نسخه کتابخانه 0.0.9
نگهدارنده ['Ryan Northey']
ایمیل نگهدارنده ['ryan@synca.io']
نویسنده Ryan Northey
ایمیل نویسنده ryan@synca.io
آدرس صفحه اصلی https://github.com/envoyproxy/pytooling/tree/main/abstracts
آدرس اینترنتی https://pypi.org/project/abstracts/
مجوز Apache Software License 2.0
abstracts ========= Abstract class and interface definitions. Create an ``abstract.Abstraction`` ---------------------------------- An ``Abstraction`` is a ``metaclass`` for defining abstract classes. Let's define an abstract ``AFoo`` class and give it an abstract ``do_foo`` method. Like any python class, an ``Abstraction`` can have any name, but it may be helpful to distinguish abstract classes from others by prefixing their name with ``A``. .. code-block:: pycon >>> import abc >>> import abstracts >>> class AFoo(metaclass=abstracts.Abstraction): ... ... @abc.abstractmethod ... def do_foo(self): ... raise NotImplementedError Abstract classes **cannot** be instantiated directly. .. code-block:: pycon >>> AFoo() Traceback (most recent call last): ... TypeError: Can't instantiate abstract class AFoo with abstract method... do_foo Create an ``implementer`` for an ``abstract.Abstraction`` --------------------------------------------------------- In order to make use of ``AFoo``, we need to create an implementer for it. .. code-block:: pycon >>> @abstracts.implementer(AFoo) ... class Foo: ... pass The implementer **must** implement all of the abstract methods, defined by its abstract classes. .. code-block:: pycon >>> Foo() Traceback (most recent call last): ... TypeError: Can't instantiate abstract class Foo with abstract method... do_foo >>> @abstracts.implementer(AFoo) ... class Foo2: ... ... def do_foo(self): ... return "DID FOO" >>> Foo2() <__main__.Foo2 object at ...> An implementer inherits from its ``Abstractions`` ------------------------------------------------- An ``implementer`` class is a subclass of its ``Abstraction``. .. code-block:: pycon >>> issubclass(Foo2, AFoo) True Likewise an instance of an implementer is an instance of its ``Abstraction`` .. code-block:: pycon >>> isinstance(Foo2(), AFoo) True The ``Abstraction`` class can be seen in the class ``bases``, and the methods of the ``Abstraction`` can be invoked by the implementer. .. code-block:: pycon >>> import inspect >>> AFoo in inspect.getmro(Foo2) True Create an ``implementer`` that implements multiple ``Abstraction`` s. --------------------------------------------------------------------- An implementer can implement multiple abstractions. Let's create a second abstraction. .. code-block:: pycon >>> class ABar(metaclass=abstracts.Abstraction): ... ... @abc.abstractmethod ... def do_bar(self): ... raise NotImplementedError And now we can create an implementer that implememts both the ``AFoo`` and ``ABar`` ``Abstraction`` s. .. code-block:: pycon >>> @abstracts.implementer((AFoo, ABar)) ... class FooBar: ... ... def do_foo(self): ... return "DID FOO" ... ... def do_bar(self): ... return "DID BAR" >>> FooBar() <__main__.FooBar object at ...> Defining abstract properties ---------------------------- Properties can be defined in an abstract class, and just like with normal methods, they must be implemented by any implementers. .. code-block:: pycon >>> class AMover(metaclass=abstracts.Abstraction): ... ... @property ... @abc.abstractmethod ... def speed(self): ... return 5 ... ... @property ... @abc.abstractmethod ... def direction(self): ... return "forwards" Calling ``super()`` on an ``abstractmethod`` -------------------------------------------- Just like with pythons "Abstract Base Classes" you can call ``super()`` in an ``abstractmethod``, to invoke an abstract implementation. .. code-block:: pycon >>> @abstracts.implementer(AMover) ... class Mover: ... ... @property ... def direction(self): ... return "backwards" ... ... @property ... def speed(self): ... return super().speed This custom implementation of ``AMover`` **must** implement both ``speed`` and ``direction``, even if its implementation invokes the abstract implementation. In this case it uses the default/abstract implementation of ``speed`` while providing its own implementation of ``direction``. .. code-block:: pycon >>> mover = Mover() >>> mover <__main__.Mover object at ...> >>> mover.speed 5 >>> mover.direction 'backwards' Defining an ``abstracts.Interface`` class ----------------------------------------- An ``Interface`` is much like an ``Abstraction``, but with a few differences. An ``Interface`` can only define methods with the ``@interfacemethod`` decorator. It cannot define normal methods or methods with the ``@abstractmethod``, only methods with ``@interfacemethod``. An ``@interfacemethod`` if invoked will always raise an ``NotImplementedError``, and therefore cannot be used as an abstract implementation. Lets add an ``Interface`` class that we can use. In the way that it may be helpful to distinguish an ``Abstraction`` from other types of classes, it may be also useful to distinguish an ``Interface`` by using an ``I`` prefix when naming them. .. code-block:: pycon >>> class IGeared(metaclass=abstracts.Interface): ... ... @property ... @abstracts.interfacemethod ... def number_of_gears(self): ... # Raising an error is ~superfluous as the decorator will raise ... # anyway if the method is invoked. ... raise NotImplementedError Implementing an ``Interface`` ----------------------------- Just like with an ``Abstraction``, an ``Interface`` can be implemented using the ``@implementer`` decorator. An implementer, can implement a combination of ``Abstractions`` and ``Interfaces``. .. code-block:: pycon >>> @abstracts.implementer((AMover, IGeared)) ... class Bicycle: ... ... @property ... def direction(self): ... return super().direction ... ... @property ... def speed(self): ... return super().speed ... ... @property ... def number_of_gears(self): ... return 7 >>> Bicycle().number_of_gears 7 An implementer does **not** inherit from its ``Interfaces`` ----------------------------------------------------------- An ``implementer`` class is a subclass of its ``Interfaces``. .. code-block:: pycon >>> issubclass(Bicycle, AMover) True >>> issubclass(Bicycle, IGeared) True Likewise an instance of an implementer is an instance of its ``Interfaces`` .. code-block:: pycon >>> isinstance(Bicycle(), AMover) True >>> isinstance(Bicycle(), IGeared) True Unlike with ``Abstractions`` it does **not** however, inherit from its ``Interfaces``. .. code-block:: pycon >>> AMover in inspect.getmro(Bicycle) True >>> IGeared in inspect.getmro(Bicycle) False ``@interfacemethods`` can never be invoked ------------------------------------------ The key thing to remember is that you cannot call ``super()`` on any ``@interfacemethod``, or directly invoke it. If it was defined as part of an ``Interface`` you will receive an ``AttributeError``, as the implementation does not inherit directly from the interface. .. code-block:: pycon >>> @abstracts.implementer((AMover, IGeared)) ... class BrokenBicycle: ... ... @property ... def direction(self): ... return super().direction ... ... @property ... def speed(self): ... return super().speed ... ... @property ... def number_of_gears(self): ... return super().number_of_gears >>> BrokenBicycle().number_of_gears Traceback (most recent call last): ... AttributeError: 'super' object has no attribute 'number_of_gears' .. warning:: Misuse of this class can have `unintended consequences <https://www.dailymotion.com/video/x2howud>`_ If you invoke ``super()`` on an ``@interfacemethod`` defined as part of an ``Abstraction`` it will raise ``NotImplementedError``. As an ``Interface`` can only hold this type of method, you can never invoke any of its methods. Doing so directly will raising a ``NotImplementedError``. .. code-block:: pycon >>> IGeared.number_of_gears.__get__(Bicycle()) Traceback (most recent call last): ... NotImplementedError Combining ``@abstractmethod`` and ``@interfacemethod`` in an ``Abstraction`` ---------------------------------------------------------------------------- As ``Interfaces`` are "pure", they cannot use ``@abstractmethod`` or contain any implementation. An ``Abstraction`` on the other hand can combine both. Lets create a pure ``Interface`` that represents a "shed". .. code-block:: pycon >>> class IShed(metaclass=abstracts.Interface): ... ... @property ... @abstracts.interfacemethod ... def size(self): ... raise NotImplementedError We can use this interface to create an ``ABikeShed`` ``Abstraction`` .. code-block:: pycon >>> class ABikeShed(IShed, metaclass=abstracts.Abstraction): ... ... @property ... @abstracts.interfacemethod ... def max_bike_size(self): ... raise NotImplementedError ... ... @abc.abstractmethod ... def get_capacity(self): ... return int(self.size / self.max_bike_size) We can now create an implementation. It will need to define both the ``size`` and the ``max_bike_size``, as these are ``interfacemethods``. It can, however, make use of the abstract implementation of ``get_capacity``, even if it must be defined. .. code-block:: pycon >>> @abstracts.implementer(ABikeShed) ... class BikeShed: ... ... @property ... def max_bike_size(self): ... return 7 ... ... @property ... def size(self): ... return 161 ... ... def get_capacity(self): ... return super().get_capacity() >>> bikeshed = BikeShed() >>> bikeshed.get_capacity() 23


نیازمندی

مقدار نام
- flake8
- wheel
- pytest
- pytest-coverage
- pytest-patches
- mypy


زبان مورد نیاز

مقدار نام
>=3.5 Python


نحوه نصب


نصب پکیج whl abstracts-0.0.9:

    pip install abstracts-0.0.9.whl


نصب پکیج tar.gz abstracts-0.0.9:

    pip install abstracts-0.0.9.tar.gz