Hướng dẫn how does abc work python? - làm thế nào để abc hoạt động python?

Mã nguồn: lib/abc.py Lib/abc.py


Mô -đun này cung cấp cơ sở hạ tầng để xác định các lớp cơ sở trừu tượng (ABC) trong Python, như được nêu trong PEP 3119; Xem PEP cho lý do tại sao điều này đã được thêm vào Python. (Xem thêm PEP 3141 và mô -đun

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
1 liên quan đến phân cấp loại cho các số dựa trên ABC.)abstract base classes (ABCs) in Python, as outlined in PEP 3119; see the PEP for why this was added to Python. (See also PEP 3141 and the
from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
1 module regarding a type hierarchy for numbers based on ABCs.)

Mô -đun

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
2 có một số lớp cụ thể xuất phát từ ABC; Những điều này, tất nhiên, có thể bắt nguồn thêm. Ngoài ra, mô hình con
from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
3 có một số ABC có thể được sử dụng để kiểm tra xem một lớp hoặc phiên bản cung cấp một giao diện cụ thể, ví dụ, nếu nó có thể băm hay nếu đó là ánh xạ.

Mô -đun này cung cấp Metaclass

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
4 để xác định ABC và lớp trợ giúp
from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
5 để xác định thay thế ABC thông qua kế thừa:

classabc.abc¶abc.ABC

Một lớp trợ giúp có

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
4 là metaclass của nó. Với lớp này, một lớp cơ sở trừu tượng có thể được tạo bằng cách đơn giản xuất phát từ
from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
5 Tránh đôi khi sử dụng Metaclass khó hiểu, ví dụ::

from abc import ABC

class MyABC(ABC):
    pass

Lưu ý rằng loại

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
5 vẫn là
from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
4, do đó kế thừa từ
from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
5 yêu cầu các biện pháp phòng ngừa thông thường liên quan đến việc sử dụng Metaclass, vì nhiều kế thừa có thể dẫn đến xung đột metaclass. Người ta cũng có thể xác định một lớp cơ sở trừu tượng bằng cách truyền từ khóa Metaclass và sử dụng trực tiếp
from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
4, ví dụ:

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass

Mới trong phiên bản 3.4.

classabc.abcmeta¶abc.ABCMeta

Metaclass để xác định các lớp cơ sở trừu tượng (ABC).

Sử dụng metaclass này để tạo ABC. Một ABC có thể được phân lớp trực tiếp, và sau đó hoạt động như một lớp hỗn hợp. Bạn cũng có thể đăng ký các lớp bê tông không liên quan (thậm chí các lớp tích hợp) và các ABC không liên quan là các lớp con ảo ảo-những lớp này và con cháu của họ sẽ được coi là các lớp con của ABC đăng ký bởi chức năng ____22 tích hợp, nhưng việc đăng ký ABC sẽ không hiển thị trong MRO của họ (thứ tự phân giải phương thức) cũng như các triển khai phương thức sẽ được xác định bởi ABC đăng ký được gọi (thậm chí không qua

from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
3). 1

Các lớp được tạo bằng metaclass của

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
4 có phương pháp sau:

Đăng ký (lớp con)(subclass)

Đăng ký lớp con dưới dạng lớp con ảo ảo của ABC này. Ví dụ:

from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)

Đã thay đổi trong phiên bản 3.3: Trả về lớp con đã đăng ký, để cho phép sử dụng làm người trang trí lớp.Returns the registered subclass, to allow usage as a class decorator.

Bạn cũng có thể ghi đè phương thức này trong một lớp cơ sở trừu tượng:

__SubClasshook __ (lớp con) ¶(subclass)

(Phải được định nghĩa là phương thức lớp.)

Kiểm tra xem phân lớp con được coi là một lớp con của ABC này. Điều này có nghĩa là bạn có thể tùy chỉnh hành vi của

from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
5 xa hơn mà không cần phải gọi
from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
6 trên mỗi lớp bạn muốn xem xét một lớp con của ABC. (Phương pháp lớp này được gọi từ phương thức
from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
7 của ABC.)

Phương pháp này sẽ trả về

from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
8,
from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
9 hoặc
class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)
0. Nếu nó trả về
from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
8, lớp con được coi là một lớp con của ABC này. Nếu nó trả về
from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
9, lớp con không được coi là một lớp con của ABC này, ngay cả khi nó thường là một. Nếu nó trả về
class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)
0, kiểm tra lớp con được tiếp tục với cơ chế thông thường.

Để trình diễn các khái niệm này, hãy xem ví dụ này định nghĩa ABC:

class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)

ABC

class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)
4 định nghĩa phương pháp ITBER tiêu chuẩn,
class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)
5, là một phương pháp trừu tượng. Việc thực hiện được đưa ra ở đây vẫn có thể được gọi từ các lớp con. Phương pháp
class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)
6 cũng là một phần của lớp cơ sở trừu tượng
class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)
4, nhưng nó không phải được ghi đè trong các lớp có nguồn gốc không phải là Abstract.

Phương thức lớp

class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)
8 được xác định ở đây nói rằng bất kỳ lớp nào có phương thức
class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)
5 trong
class C(ABC):
    @abstractmethod
    def my_abstract_method(self, arg1):
        ...
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg2):
        ...
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg3):
        ...

    @property
    @abstractmethod
    def my_abstract_property(self):
        ...
    @my_abstract_property.setter
    @abstractmethod
    def my_abstract_property(self, val):
        ...

    @abstractmethod
    def _get_x(self):
        ...
    @abstractmethod
    def _set_x(self, val):
        ...
    x = property(_get_x, _set_x)
0 của nó (hoặc theo một trong các lớp cơ sở của nó, được truy cập thông qua danh sách
class C(ABC):
    @abstractmethod
    def my_abstract_method(self, arg1):
        ...
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg2):
        ...
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg3):
        ...

    @property
    @abstractmethod
    def my_abstract_property(self):
        ...
    @my_abstract_property.setter
    @abstractmethod
    def my_abstract_property(self, val):
        ...

    @abstractmethod
    def _get_x(self):
        ...
    @abstractmethod
    def _set_x(self, val):
        ...
    x = property(_get_x, _set_x)
1) cũng được coi là
class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)
4.

Cuối cùng, dòng cuối cùng làm cho

class C(ABC):
    @abstractmethod
    def my_abstract_method(self, arg1):
        ...
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg2):
        ...
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg3):
        ...

    @property
    @abstractmethod
    def my_abstract_property(self):
        ...
    @my_abstract_property.setter
    @abstractmethod
    def my_abstract_property(self, val):
        ...

    @abstractmethod
    def _get_x(self):
        ...
    @abstractmethod
    def _set_x(self, val):
        ...
    x = property(_get_x, _set_x)
3 một lớp con ảo của
class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)
4, mặc dù nó không xác định phương thức
class Foo:
    def __getitem__(self, index):
        ...
    def __len__(self):
        ...
    def get_iterator(self):
        return iter(self)

class MyIterable(ABC):

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    def get_iterator(self):
        return self.__iter__()

    @classmethod
    def __subclasshook__(cls, C):
        if cls is MyIterable:
            if any("__iter__" in B.__dict__ for B in C.__mro__):
                return True
        return NotImplemented

MyIterable.register(Foo)
5 (nó sử dụng giao thức có thể lặp lại kiểu cũ, được định nghĩa theo định nghĩa của
class C(ABC):
    @abstractmethod
    def my_abstract_method(self, arg1):
        ...
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg2):
        ...
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg3):
        ...

    @property
    @abstractmethod
    def my_abstract_property(self):
        ...
    @my_abstract_property.setter
    @abstractmethod
    def my_abstract_property(self, val):
        ...

    @abstractmethod
    def _get_x(self):
        ...
    @abstractmethod
    def _set_x(self, val):
        ...
    x = property(_get_x, _set_x)
6 và
class C(ABC):
    @abstractmethod
    def my_abstract_method(self, arg1):
        ...
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg2):
        ...
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg3):
        ...

    @property
    @abstractmethod
    def my_abstract_property(self):
        ...
    @my_abstract_property.setter
    @abstractmethod
    def my_abstract_property(self, val):
        ...

    @abstractmethod
    def _get_x(self):
        ...
    @abstractmethod
    def _set_x(self, val):
        ...
    x = property(_get_x, _set_x)
7). Lưu ý rằng điều này sẽ không cung cấp
class C(ABC):
    @abstractmethod
    def my_abstract_method(self, arg1):
        ...
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg2):
        ...
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg3):
        ...

    @property
    @abstractmethod
    def my_abstract_property(self):
        ...
    @my_abstract_property.setter
    @abstractmethod
    def my_abstract_property(self, val):
        ...

    @abstractmethod
    def _get_x(self):
        ...
    @abstractmethod
    def _set_x(self, val):
        ...
    x = property(_get_x, _set_x)
8 có sẵn như một phương pháp của
class C(ABC):
    @abstractmethod
    def my_abstract_method(self, arg1):
        ...
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg2):
        ...
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg3):
        ...

    @property
    @abstractmethod
    def my_abstract_property(self):
        ...
    @my_abstract_property.setter
    @abstractmethod
    def my_abstract_property(self, val):
        ...

    @abstractmethod
    def _get_x(self):
        ...
    @abstractmethod
    def _set_x(self, val):
        ...
    x = property(_get_x, _set_x)
3, vì vậy nó được cung cấp riêng biệt.

Mô -đun

class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
0 cũng cung cấp bộ trang trí sau:

@abc.abstractmethod¶abc.abstractmethod

Một nhà trang trí chỉ ra các phương pháp trừu tượng.

Sử dụng bộ trang trí này yêu cầu lớp Metaclass của lớp là

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
4 hoặc có nguồn gốc từ nó. Một lớp có metaclass có nguồn gốc từ
from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
4 không thể được khởi tạo trừ khi tất cả các phương thức và thuộc tính trừu tượng của nó được ghi đè. Các phương thức trừu tượng có thể được gọi bằng cách sử dụng bất kỳ cơ chế cuộc gọi siêu bình thường nào.
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3 có thể được sử dụng để khai báo các phương thức trừu tượng cho các thuộc tính và mô tả.

Động lực thêm các phương thức trừu tượng vào một lớp hoặc cố gắng sửa đổi trạng thái trừu tượng của một phương thức hoặc lớp sau khi nó được tạo, chỉ được hỗ trợ bằng hàm

class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
4.
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3 chỉ ảnh hưởng đến các lớp con có nguồn gốc bằng cách sử dụng thừa kế thường xuyên; Các lớp con ảo ảo đã đăng ký với phương pháp ABC
from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
6 không bị ảnh hưởng.

Khi

class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3 được áp dụng kết hợp với các mô tả phương pháp khác, nó nên được áp dụng làm chất trang trí trong cùng, như thể hiện trong các ví dụ sử dụng sau đây:

class C(ABC):
    @abstractmethod
    def my_abstract_method(self, arg1):
        ...
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg2):
        ...
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg3):
        ...

    @property
    @abstractmethod
    def my_abstract_property(self):
        ...
    @my_abstract_property.setter
    @abstractmethod
    def my_abstract_property(self, val):
        ...

    @abstractmethod
    def _get_x(self):
        ...
    @abstractmethod
    def _set_x(self, val):
        ...
    x = property(_get_x, _set_x)

Để tương tác chính xác với máy móc lớp cơ sở trừu tượng, bộ mô tả phải tự xác định là trừu tượng bằng cách sử dụng

class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
8. Nói chung, thuộc tính này phải là
from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
8 nếu bất kỳ phương pháp nào được sử dụng để soạn thảo mô tả là trừu tượng. Ví dụ, Python sườn tích hợp
class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
0 có tương đương với:

class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))

Ghi chú

Không giống như các phương thức trừu tượng Java, các phương pháp trừu tượng này có thể có một triển khai. Việc triển khai này có thể được gọi thông qua cơ chế

from abc import ABC

class MyABC(ABC):
    pass

MyABC.register(tuple)

assert issubclass(tuple, MyABC)
assert isinstance((), MyABC)
3 từ lớp ghi đè nó. Điều này có thể hữu ích như một điểm cuối cho một cuộc gọi siêu trong một khung sử dụng nhiều nội dung hợp tác.

Mô -đun

class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
0 cũng hỗ trợ các nhà trang trí kế thừa sau:

@ABC.AbstractClassMethod¶abc.abstractclassmethod

Mới trong phiên bản 3.2.

Không dùng nữa kể từ phiên bản 3.3: Bây giờ có thể sử dụng

class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
3 với
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3, làm cho bộ trang trí này trở nên dư thừa.It is now possible to use
class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
3 with
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3, making this decorator redundant.

Một lớp con của

class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
5 tích hợp, chỉ ra một lớp học trừu tượng. Nếu không, nó tương tự như
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3.

Trường hợp đặc biệt này không được chấp nhận, vì người trang trí

class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
5 hiện được xác định chính xác là trừu tượng khi được áp dụng cho một phương pháp trừu tượng:

class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...

@abc.abstractstaticmethod¶abc.abstractstaticmethod

Mới trong phiên bản 3.2.

Không dùng nữa kể từ phiên bản 3.3: Bây giờ có thể sử dụng

class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
3 với
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3, làm cho bộ trang trí này trở nên dư thừa.It is now possible to use
class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
8 with
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3, making this decorator redundant.

Một lớp con của

class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
5 tích hợp, chỉ ra một lớp học trừu tượng. Nếu không, nó tương tự như
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3.

Trường hợp đặc biệt này không được chấp nhận, vì người trang trí

class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
5 hiện được xác định chính xác là trừu tượng khi được áp dụng cho một phương pháp trừu tượng:

class C(ABC):
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg):
        ...

@abc.abstractstaticmethod¶abc.abstractproperty

Không dùng nữa kể từ phiên bản 3.3: Bây giờ có thể sử dụng

class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
8 với
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3, làm cho bộ trang trí này trở nên dư thừa.It is now possible to use
class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
0,
class C(ABC):
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg):
        ...
4,
class C(ABC):
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg):
        ...
5 and
class C(ABC):
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg):
        ...
6 with
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3, making this decorator redundant.

Một lớp con của

class C(ABC):
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg):
        ...
0 tích hợp, chỉ ra một staticmethod trừu tượng. Nếu không, nó tương tự như
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3.

Trường hợp đặc biệt này không được chấp nhận, vì người trang trí

class C(ABC):
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg):
        ...
0 hiện được xác định chính xác là trừu tượng khi được áp dụng cho một phương pháp trừu tượng:

class C(ABC):
    @property
    @abstractmethod
    def my_abstract_property(self):
        ...

@abc.abstractproperty¶

class C(ABC):
    @property
    def x(self):
        ...

    @x.setter
    @abstractmethod
    def x(self, val):
        ...

Đã không dùng từ phiên bản 3.3: Hiện tại có thể sử dụng

class C(ABC):
    @classmethod
    @abstractmethod
    def my_abstract_classmethod(cls, arg):
        ...
0,
class C(ABC):
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg):
        ...
4,
class C(ABC):
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg):
        ...
5 và
class C(ABC):
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg):
        ...
6 với
class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
3, làm cho người trang trí này trở nên dư thừa.

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
0

Một lớp con của

class C(ABC):
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg):
        ...
8 tích hợp, chỉ ra một thuộc tính trừu tượng.

Trường hợp đặc biệt này không được chấp nhận, vì người trang trí
class C(ABC):
    @staticmethod
    @abstractmethod
    def my_abstract_staticmethod(arg):
        ...
8 hiện được xác định chính xác là trừu tượng khi được áp dụng cho một phương pháp trừu tượng:
get_cache_token()

Ví dụ trên xác định một thuộc tính chỉ đọc; Bạn cũng có thể định nghĩa một thuộc tính trừu tượng đọc-viết bằng cách đánh dấu một cách thích hợp một hoặc nhiều phương thức cơ bản là trừu tượng:

Nếu chỉ có một số thành phần là trừu tượng, chỉ các thành phần đó cần được cập nhật để tạo một thuộc tính cụ thể trong một lớp con:

Mô -đun

class Descriptor:
    ...
    @property
    def __isabstractmethod__(self):
        return any(getattr(f, '__isabstractmethod__', False) for
                   f in (self._fget, self._fset, self._fdel))
0 cũng cung cấp các chức năng sau:

abc.get_cache_token ()update_abstractmethods(cls)

Trả về mã bộ nhớ cache lớp cơ sở trừu tượng hiện tại.

Mã thông báo là một đối tượng mờ đục (hỗ trợ kiểm tra bình đẳng) xác định phiên bản hiện tại của bộ đệm lớp cơ sở trừu tượng cho các lớp con ảo. Mã thông báo thay đổi với mỗi cuộc gọi đến

class C(ABC):
    @property
    @abstractmethod
    def my_abstract_property(self):
        ...
1 trên bất kỳ ABC nào.

Mới trong phiên bản 3.4.

Ghi chú

ABC.UPDATE_ABSTRACTMETHODS (CLS) ¶

Một chức năng để tính toán lại một trạng thái trừu tượng của lớp trừu tượng. Hàm này nên được gọi là nếu một phương thức trừu tượng của lớp đã được thực hiện hoặc thay đổi sau khi nó được tạo. Thông thường, chức năng này nên được gọi từ trong một người trang trí lớp.

Trả về CLS, để cho phép sử dụng như một người trang trí lớp.

1

Nếu CLS không phải là một ví dụ của

from abc import ABCMeta

class MyABC(metaclass=ABCMeta):
    pass
4, không làm gì cả.

Việc sử dụng ABC trong Python là gì?

Mô -đun này cung cấp cơ sở hạ tầng để xác định các lớp cơ sở trừu tượng (ABC) trong Python, như được nêu trong PEP 3119; Xem PEP cho lý do tại sao điều này đã được thêm vào Python. (Xem thêm PEP 3141 và mô -đun số liên quan đến phân cấp loại cho các số dựa trên ABC.)provides the infrastructure for defining abstract base classes (ABCs) in Python, as outlined in PEP 3119; see the PEP for why this was added to Python. (See also PEP 3141 and the numbers module regarding a type hierarchy for numbers based on ABCs.)

ABC có được xây dựng trong Python không?

Abs () là một chức năng tích hợp có sẵn với Python và nó sẽ trả lại cho bạn giá trị tuyệt đối cho đầu vào đã cho. Giá trị là một giá trị đầu vào được trao cho abs () để có được giá trị tuyệt đối. Nó có thể là một số nguyên, phao hoặc một số phức. Phương thức ABS () có một đối số, tức là giá trị bạn muốn nhận được tuyệt đối., and it will return you the absolute value for the input given. Value is an input value to be given to abs() to get the absolute value. It can be an integer, a float, or a complex number. The abs() method takes one argument, i.e. the value you want to get the absolute.

Phương pháp bê tông trong Python là gì?

Các lớp trừu tượng cũng có thể chứa các phương pháp cụ thể có việc thực hiện phương pháp và có thể được sử dụng bởi tất cả các lớp cụ thể.Để xác định một phương pháp cụ thể trong một lớp trừu tượng, chúng tôi chỉ cần xác định một phương thức với việc thực hiện và không trang trí nó với bộ trang trí @abstractmethod.have the implementation of the method and can be used by all the concrete classes. To define a concrete method in an abstract class, we simply define a method with implementation and don't decorate it with the @abstractmethod decorator.

Sự khác biệt giữa ABC và ABCMeta là gì?

Sự khác biệt duy nhất là trong trường hợp trước, bạn cần một kế thừa đơn giản và ở sau bạn cần chỉ định Metaclass.Từ những gì mới trong Python 3.4 (nhấn mạnh của tôi): Lớp mới ABC có ABCMETA là lớp meta của nó.Sử dụng ABC làm lớp cơ sở về cơ bản có tác dụng tương tự như chỉ định metaclass = abc.in the former case you need a simple inheritance and in the latter you need to specify the metaclass. From What's new in Python 3.4(emphasis mine): New class ABC has ABCMeta as its meta class. Using ABC as a base class has essentially the same effect as specifying metaclass=abc.