Các đối tượng là sự trừu tượng hóa dữ liệu của Python. Tất cả dữ liệu trong chương trình Python được biểu diễn bằng đối tượng hoặc bằng quan hệ giữa các đối tượng. [Theo một nghĩa nào đó, và phù hợp với mô hình “máy tính chương trình được lưu trữ” của Von Neumann, mã cũng được biểu diễn bằng các đối tượng. ]
Mỗi đối tượng có một danh tính, một loại và một giá trị. An object’s identity never changes once it has been created; you may think of it as the object’s address in memory. The ‘’ operator compares the identity of two objects; the function returns an integer representing its identity
CPython implementation detail. For CPython,
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule9 is the memory address where
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass0 is stored
An object’s type determines the operations that the object supports [e. g. , “does it have a length?”] and also defines the possible values for objects of that type. The function returns an object’s type [which is an object itself]. Like its identity, an object’s type is also unchangeable.
The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. [The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle. ] An object’s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable
Objects are never explicitly destroyed; however, when they become unreachable they may be garbage-collected. An implementation is allowed to postpone garbage collection or omit it altogether — it is a matter of implementation quality how garbage collection is implemented, as long as no objects are collected that are still reachable
CPython implementation detail. CPython currently uses a reference-counting scheme with [optional] delayed detection of cyclically linked garbage, which collects most objects as soon as they become unreachable, but is not guaranteed to collect garbage containing circular references. See the documentation of the module for information on controlling the collection of cyclic garbage. Other implementations act differently and CPython may change. Do not depend on immediate finalization of objects when they become unreachable [so you should always close files explicitly]
Note that the use of the implementation’s tracing or debugging facilities may keep objects alive that would normally be collectable. Also note that catching an exception with a ‘…’ statement may keep objects alive
Some objects contain references to “external” resources such as open files or windows. It is understood that these resources are freed when the object is garbage-collected, but since garbage collection is not guaranteed to happen, such objects also provide an explicit way to release the external resource, usually a
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass5 method. Programs are strongly recommended to explicitly close such objects. The ‘…’ statement and the ‘’ statement provide convenient ways to do this
Some objects contain references to other objects; these are called containers. Ví dụ về vùng chứa là bộ dữ liệu, danh sách và từ điển. Các tham chiếu là một phần giá trị của vùng chứa. Trong hầu hết các trường hợp, khi chúng ta nói về giá trị của một vùng chứa, chúng ta ngụ ý các giá trị, không phải danh tính của các đối tượng được chứa; . Vì vậy, nếu một bộ chứa bất biến [như bộ dữ liệu] chứa tham chiếu đến một đối tượng có thể thay đổi, thì giá trị của nó sẽ thay đổi nếu đối tượng có thể thay đổi đó bị thay đổi
Các loại ảnh hưởng đến hầu hết các khía cạnh của hành vi đối tượng. Ngay cả tầm quan trọng của danh tính đối tượng cũng bị ảnh hưởng theo một nghĩa nào đó. đối với các loại bất biến, các hoạt động tính toán các giá trị mới thực sự có thể trả về một tham chiếu đến bất kỳ đối tượng hiện có nào có cùng loại và giá trị, trong khi đối với các đối tượng có thể thay đổi thì điều này không được phép. e. g. , sau
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass9,
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']0 và
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']1 có thể hoặc không thể tham chiếu đến cùng một đối tượng với giá trị một, tùy thuộc vào cách triển khai, nhưng sau
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']2,
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']3 và
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']4 được đảm bảo tham chiếu đến hai danh sách trống khác nhau, duy nhất, mới được tạo. [Lưu ý rằng
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']5 gán cùng một đối tượng cho cả
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']3 và
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']4. ]
3. 2. Hệ thống phân cấp loại tiêu chuẩn
Dưới đây là danh sách các loại được tích hợp sẵn trong Python. Các mô-đun mở rộng [được viết bằng C, Java hoặc các ngôn ngữ khác, tùy thuộc vào việc triển khai] có thể xác định các loại bổ sung. Các phiên bản tương lai của Python có thể thêm các loại vào hệ thống phân cấp loại [e. g. , số hữu tỷ, mảng số nguyên được lưu trữ hiệu quả, v.v. ], mặc dù những phần bổ sung như vậy thường sẽ được cung cấp thông qua thư viện chuẩn để thay thế
Một số mô tả loại bên dưới chứa đoạn liệt kê 'thuộc tính đặc biệt. ' Đây là những thuộc tính cung cấp quyền truy cập vào việc triển khai và không dành cho mục đích sử dụng chung. Định nghĩa của họ có thể thay đổi trong tương lai
Không cóLoại này có một giá trị duy nhất. Có một đối tượng duy nhất với giá trị này. Đối tượng này được truy cập thông qua tên dựng sẵn
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8. Nó được sử dụng để biểu thị sự vắng mặt của một giá trị trong nhiều tình huống, e. g. , nó được trả về từ các hàm không trả về bất cứ thứ gì một cách rõ ràng. Giá trị thật của nó là saiKhông được thực hiện
Loại này có một giá trị duy nhất. Có một đối tượng duy nhất với giá trị này. Đối tượng này được truy cập thông qua tên dựng sẵn
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']9. Numeric methods and rich comparison methods should return this value if they do not implement the operation for the operands provided. [The interpreter will then try the reflected operation, or some other fallback, depending on the operator. ] It should not be evaluated in a boolean context
See for more details
Changed in version 3. 9. Evaluating
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']9 in a boolean context is deprecated. While it currently evaluates as true, it will emit a . It will raise a in a future version of Python. Ellipsis
This type has a single value. There is a single object with this value. This object is accessed through the literal
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook3 or the built-in name
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook4. Its truth value is true
These are created by numeric literals and returned as results by arithmetic operators and arithmetic built-in functions. Numeric objects are immutable; once created their value never changes. Python numbers are of course strongly related to mathematical numbers, but subject to the limitations of numerical representation in computers
The string representations of the numeric classes, computed by and , have the following properties
They are valid numeric literals which, when passed to their class constructor, produce an object having the value of the original numeric
The representation is in base 10, when possible
Leading zeros, possibly excepting a single zero before a decimal point, are not shown
Trailing zeros, possibly excepting a single zero after a decimal point, are not shown
A sign is shown only when the number is negative
Python distinguishes between integers, floating point numbers, and complex numbers
These represent elements from the mathematical set of integers [positive and negative]
There are two types of integers
Integers []These represent numbers in an unlimited range, subject to available [virtual] memory only. For the purpose of shift and mask operations, a binary representation is assumed, and negative numbers are represented in a variant of 2’s complement which gives the illusion of an infinite string of sign bits extending to the left
Booleans []These represent the truth values False and True. The two objects representing the values
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass1 and
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass2 are the only Boolean objects. The Boolean type is a subtype of the integer type, and Boolean values behave like the values 0 and 1, respectively, in almost all contexts, the exception being that when converted to a string, the strings
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass3 or
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass4 are returned, respectively
The rules for integer representation are intended to give the most meaningful interpretation of shift and mask operations involving negative integers
[]These represent machine-level double precision floating point numbers. You are at the mercy of the underlying machine architecture [and C or Java implementation] for the accepted range and handling of overflow. Python does not support single-precision floating point numbers; the savings in processor and memory usage that are usually the reason for using these are dwarfed by the overhead of using objects in Python, so there is no reason to complicate the language with two kinds of floating point numbers
[]These represent complex numbers as a pair of machine-level double precision floating point numbers. The same caveats apply as for floating point numbers. The real and imaginary parts of a complex number
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass9 can be retrieved through the read-only attributes
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]0 and
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]1trình tự
These represent finite ordered sets indexed by non-negative numbers. The built-in function returns the number of items of a sequence. When the length of a sequence is n, the index set contains the numbers 0, 1, …, n-1. Item i of sequence a is selected by
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]3
Sequences also support slicing.
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]4 selects all items with index k such that i
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]5 k
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]6 j. When used as an expression, a slice is a sequence of the same type. This implies that the index set is renumbered so that it starts at 0
Some sequences also support “extended slicing” with a third “step” parameter.
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]7 selects all items of a with index x where
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]8, n
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]9
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]0 and i
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]5 x
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]6 j
Sequences are distinguished according to their mutability
Immutable sequencesAn object of an immutable sequence type cannot change once it is created. [If the object contains references to other objects, these other objects may be mutable and may be changed; however, the collection of objects directly referenced by an immutable object cannot change. ]
The following types are immutable sequences
StringsA string is a sequence of values that represent Unicode code points. All the code points in the range
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]3 can be represented in a string. Python doesn’t have a char type; instead, every code point in the string is represented as a string object with length
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]4. The built-in function converts a code point from its string form to an integer in the range
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]6; converts an integer in the range
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]6 to the corresponding length
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]4 string object. can be used to convert a to using the given text encoding, and can be used to achieve the opposite. Tuples
The items of a tuple are arbitrary Python objects. Tuples of two or more items are formed by comma-separated lists of expressions. A tuple of one item [a ‘singleton’] can be formed by affixing a comma to an expression [an expression by itself does not create a tuple, since parentheses must be usable for grouping of expressions]. An empty tuple can be formed by an empty pair of parentheses
BytesA bytes object is an immutable array. The items are 8-bit bytes, represented by integers in the range 0 >> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']] 4] and the built-in constructor can be used to create bytes objects. Also, bytes objects can be decoded to strings via the method
Mutable sequencesMutable sequences can be changed after they are created. The subscription and slicing notations can be used as the target of assignment and [delete] statements
There are currently two intrinsic mutable sequence types
ListsCác mục của danh sách là các đối tượng Python tùy ý. Danh sách được hình thành bằng cách đặt một danh sách các biểu thức được phân tách bằng dấu phẩy trong dấu ngoặc vuông. [Lưu ý rằng không có trường hợp đặc biệt nào cần thiết để tạo danh sách có độ dài 0 hoặc 1. ]
Mảng byteMột đối tượng bytearray là một mảng có thể thay đổi. Chúng được tạo bởi hàm tạo tích hợp. Ngoài việc có thể thay đổi [và do đó không thể băm được], các mảng byte còn cung cấp giao diện và chức năng giống như các đối tượng bất biến
Mô-đun mở rộng cung cấp một ví dụ bổ sung về loại trình tự có thể thay đổi, cũng như mô-đun
Đặt loạiChúng đại diện cho các tập hợp hữu hạn, không có thứ tự của các đối tượng duy nhất, bất biến. Như vậy, chúng không thể được lập chỉ mục bởi bất kỳ chỉ số nào. Tuy nhiên, chúng có thể được lặp đi lặp lại và hàm tích hợp trả về số lượng mục trong một tập hợp. Các cách sử dụng phổ biến cho các tập hợp là kiểm tra tư cách thành viên nhanh, loại bỏ các bản trùng lặp khỏi một chuỗi và tính toán các phép toán như giao, hợp, hiệu và hiệu đối xứng
Đối với các phần tử tập hợp, các quy tắc bất biến tương tự áp dụng cho các khóa từ điển. Lưu ý rằng các loại số tuân theo các quy tắc thông thường để so sánh số. nếu hai số so sánh bằng nhau [e. g. ,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]4 và
a[1:2] = b4], chỉ một trong số chúng có thể được chứa trong một bộ
Hiện tại có hai loại tập hợp nội tại
bộChúng đại diện cho một tập hợp có thể thay đổi. Chúng được tạo bởi hàm tạo dựng sẵn và có thể được sửa đổi sau đó bằng một số phương thức, chẳng hạn như
a[1:2] = b6bộ đông lạnh
Chúng đại diện cho một tập hợp bất biến. Chúng được tạo bởi hàm tạo tích hợp. Vì một bộ đóng băng là bất biến và , nên nó có thể được sử dụng lại như một phần tử của một bộ khác hoặc làm khóa từ điển
ánh xạChúng đại diện cho các bộ đối tượng hữu hạn được lập chỉ mục bởi các bộ chỉ mục tùy ý. Ký hiệu chỉ số phụ
a[1:2] = b8 chọn mục được lập chỉ mục bởi
a[1:2] = b9 từ ánh xạ
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']0; . Hàm tích hợp trả về số lượng mục trong ánh xạ
Hiện tại có một loại ánh xạ nội tại duy nhất
từ điểnChúng đại diện cho các bộ đối tượng hữu hạn được lập chỉ mục bởi các giá trị gần như tùy ý. Các loại giá trị duy nhất không được chấp nhận làm khóa là các giá trị chứa danh sách hoặc từ điển hoặc các loại có thể thay đổi khác được so sánh theo giá trị thay vì theo danh tính đối tượng, lý do là việc triển khai từ điển hiệu quả yêu cầu giá trị băm của khóa không đổi. Các loại số được sử dụng cho các phím tuân theo các quy tắc thông thường để so sánh số. nếu hai số so sánh bằng nhau [e. g. ,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]4 và
a[1:2] = b4] thì chúng có thể được sử dụng thay thế cho nhau để lập chỉ mục cho cùng một mục từ điển
Từ điển duy trì thứ tự chèn, nghĩa là các khóa sẽ được tạo theo cùng thứ tự mà chúng được thêm tuần tự vào từ điển. Thay thế một khóa hiện có không thay đổi thứ tự, tuy nhiên việc xóa một khóa và cắm lại sẽ thêm khóa đó vào cuối thay vì giữ nguyên vị trí cũ
Từ điển có thể thay đổi;
Các mô-đun mở rộng và cung cấp các ví dụ bổ sung về các loại ánh xạ, cũng như mô-đun
Đã thay đổi trong phiên bản 3. 7. Từ điển không giữ nguyên thứ tự chèn trong các phiên bản Python trước 3. 6. Trong CPython 3. 6, thứ tự chèn được giữ nguyên, nhưng nó được coi là chi tiết triển khai tại thời điểm đó hơn là đảm bảo ngôn ngữ.
các loại có thể gọiĐây là những loại có thể áp dụng thao tác gọi hàm [xem phần ]
Hàm do người dùng định nghĩaMột đối tượng hàm do người dùng định nghĩa được tạo bởi một định nghĩa hàm [xem phần ]. Nó nên được gọi với một danh sách đối số chứa cùng số mục như danh sách tham số chính thức của hàm
thuộc tính đặc biệt
Thuộc tính
Nghĩa
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule09
Chuỗi tài liệu của chức năng, hoặc
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 nếu không có;
Có thể ghi
Tên chức năng
Có thể ghi
Chức năng
Mới trong phiên bản 3. 3
Có thể ghi
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule13
Tên của mô-đun mà chức năng đã được xác định trong hoặc
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 nếu không có
Có thể ghi
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule15
Một bộ chứa các giá trị đối số mặc định cho những đối số có giá trị mặc định hoặc
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 nếu không có đối số nào có giá trị mặc định
Có thể ghi
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule17
Đối tượng mã đại diện cho thân hàm đã biên dịch
Có thể ghi
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule18
Tham chiếu đến từ điển chứa các biến toàn cục của hàm — không gian tên toàn cục của mô-đun trong đó hàm được xác định
Chỉ đọc
Không gian tên hỗ trợ các thuộc tính chức năng tùy ý
Có thể ghi
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule20
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 hoặc một bộ ô chứa các liên kết cho các biến tự do của hàm. Xem bên dưới để biết thông tin về thuộc tính
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule22
Chỉ đọc
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule23
Một dict chứa chú thích của các tham số. Các khóa của dict là tên tham số và
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule24 cho chú thích trả về, nếu được cung cấp. Để biết thêm thông tin về cách làm việc với thuộc tính này, hãy xem
Có thể ghi
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule25
Một lệnh chứa các giá trị mặc định cho các tham số chỉ từ khóa
Có thể ghi
Hầu hết các thuộc tính có nhãn “Writable” kiểm tra loại giá trị được gán
Các đối tượng hàm cũng hỗ trợ nhận và đặt các thuộc tính tùy ý, chẳng hạn như có thể được sử dụng để đính kèm siêu dữ liệu vào các hàm. Ký hiệu dấu chấm thuộc tính thông thường được sử dụng để lấy và đặt các thuộc tính đó. Lưu ý rằng việc triển khai hiện tại chỉ hỗ trợ các thuộc tính chức năng trên các chức năng do người dùng xác định. Các thuộc tính chức năng trên các chức năng tích hợp có thể được hỗ trợ trong tương lai
Một đối tượng ô có thuộc tính
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule22. Điều này có thể được sử dụng để lấy giá trị của ô, cũng như đặt giá trị
Thông tin bổ sung về định nghĩa của hàm có thể được truy xuất từ đối tượng mã của nó; . Loại có thể được truy cập trong mô-đun
Phương thức sơ thẩmMột đối tượng phương thức thể hiện kết hợp một lớp, một thể hiện của lớp và bất kỳ đối tượng nào có thể gọi được [thông thường là một hàm do người dùng định nghĩa]
Thuộc tính chỉ đọc đặc biệt.
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule29 là đối tượng thể hiện của lớp,
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule30 là đối tượng hàm;
Các phương thức cũng hỗ trợ truy cập [nhưng không cài đặt] các thuộc tính hàm tùy ý trên đối tượng hàm bên dưới
Các đối tượng phương thức do người dùng định nghĩa có thể được tạo khi nhận một thuộc tính của một lớp [có thể thông qua một thể hiện của lớp đó], nếu thuộc tính đó là một đối tượng hàm do người dùng định nghĩa hoặc một đối tượng phương thức của lớp
Khi một đối tượng phương thức thể hiện được tạo bằng cách truy xuất một đối tượng hàm do người dùng định nghĩa từ một lớp thông qua một trong các thể hiện của nó, thì thuộc tính
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule29 của nó là thể hiện và đối tượng phương thức được cho là bị ràng buộc. Thuộc tính
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule30 của phương thức mới là đối tượng hàm ban đầu
Khi một đối tượng phương thức thể hiện được tạo bằng cách truy xuất một đối tượng phương thức lớp từ một lớp hoặc thể hiện, thuộc tính
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule29 của nó là chính lớp đó và thuộc tính
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule30 của nó là đối tượng hàm bên dưới phương thức lớp
Khi một đối tượng phương thức thể hiện được gọi, hàm bên dưới [
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule30] được gọi, chèn thể hiện của lớp [
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule29] trước danh sách đối số. Chẳng hạn, khi
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule43 là một lớp chứa định nghĩa cho một hàm
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule44 và
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass0 là một thể hiện của
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule43, việc gọi
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule47 tương đương với việc gọi
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule48
Khi một đối tượng phương thức thể hiện được bắt nguồn từ một đối tượng phương thức lớp, thì “thể hiện lớp” được lưu trữ trong
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule29 sẽ thực sự là chính lớp đó, do đó, việc gọi
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule47 hoặc
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule51 tương đương với việc gọi
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule52 trong đó
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule53 là hàm cơ bản
Lưu ý rằng việc chuyển đổi từ đối tượng hàm sang đối tượng phương thức thể hiện xảy ra mỗi khi thuộc tính được truy xuất từ thể hiện. Trong một số trường hợp, cách tối ưu hiệu quả là gán thuộc tính cho một biến cục bộ và gọi biến cục bộ đó. Cũng lưu ý rằng việc chuyển đổi này chỉ xảy ra đối với các chức năng do người dùng xác định; . Cũng cần lưu ý rằng các hàm do người dùng định nghĩa là các thuộc tính của một thể hiện lớp không được chuyển đổi thành các phương thức ràng buộc;
chức năng máy phát điệnHàm hoặc phương thức sử dụng câu lệnh [xem phần ] được gọi là hàm tạo. Một hàm như vậy, khi được gọi, luôn trả về một đối tượng có thể được sử dụng để thực thi phần thân của hàm. gọi phương thức của iterator sẽ khiến hàm thực thi cho đến khi nó cung cấp một giá trị bằng cách sử dụng câu lệnh
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule54. Khi hàm thực thi một câu lệnh hoặc rơi ra khỏi phần cuối, một ngoại lệ sẽ được đưa ra và trình vòng lặp sẽ đi đến phần cuối của tập hợp các giá trị được trả vềchức năng quy trình
Một hàm hoặc phương thức được định nghĩa bằng cách sử dụng được gọi là hàm coroutine. Một hàm như vậy, khi được gọi, sẽ trả về một đối tượng. Nó có thể chứa các biểu thức, cũng như và các câu lệnh. Xem thêm phần
Chức năng máy phát điện không đồng bộMột hàm hoặc phương thức được định nghĩa bằng cách sử dụng và sử dụng câu lệnh được gọi là hàm tạo không đồng bộ. Một hàm như vậy, khi được gọi, trả về một đối tượng có thể được sử dụng trong một câu lệnh để thực thi phần thân của hàm
Việc gọi phương thức của trình vòng lặp không đồng bộ sẽ trả về một phương thức mà khi được chờ đợi sẽ thực thi cho đến khi nó cung cấp một giá trị bằng cách sử dụng biểu thức. Khi hàm thực thi một câu lệnh trống hoặc rơi ra khỏi phần cuối, một ngoại lệ sẽ được đưa ra và trình lặp không đồng bộ sẽ đạt đến phần cuối của tập hợp các giá trị sẽ được tạo ra
Chức năng tích hợp sẵnMột đối tượng chức năng tích hợp là một trình bao bọc xung quanh một hàm C. Ví dụ về các hàm tích hợp sẵn là và [ là mô-đun tích hợp sẵn tiêu chuẩn]. Số lượng và loại đối số được xác định bởi hàm C. Thuộc tính chỉ đọc đặc biệt.
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule09 là chuỗi tài liệu của hàm, hoặc
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 nếu không có; Các phương pháp tích hợp
Đây thực sự là một cách ngụy trang khác của một hàm dựng sẵn, lần này chứa một đối tượng được truyền cho hàm C dưới dạng một đối số phụ ngầm định. Một ví dụ về phương thức dựng sẵn là
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule80, giả sử alist là một đối tượng danh sách. Trong trường hợp này, thuộc tính chỉ đọc đặc biệt
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule29 được đặt thành đối tượng được biểu thị bằng alistClasses
Các lớp có thể gọi được. Các đối tượng này thường đóng vai trò là nhà máy cho các phiên bản mới của chính chúng, nhưng các biến thể có thể xảy ra đối với các loại lớp ghi đè. Các đối số của cuộc gọi được chuyển đến
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule82 và, trong trường hợp điển hình, để khởi tạo thể hiện mớiTrường hợp lớp
Các thể hiện của các lớp tùy ý có thể được gọi bằng cách định nghĩa một phương thức trong lớp của chúng
mô-đunCác mô-đun là một đơn vị tổ chức cơ bản của mã Python và được tạo bởi as được gọi bởi câu lệnh hoặc bằng cách gọi các hàm như và tích hợp sẵn. Một đối tượng mô-đun có một không gian tên được triển khai bởi một đối tượng từ điển [đây là từ điển được tham chiếu bởi thuộc tính
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule18 của các hàm được xác định trong mô-đun]. Tham chiếu thuộc tính được dịch sang tra cứu trong từ điển này, e. g. ,
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule90 tương đương với
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule91. Đối tượng mô-đun không chứa đối tượng mã được sử dụng để khởi tạo mô-đun [vì nó không cần thiết sau khi quá trình khởi tạo hoàn tất]
Gán thuộc tính cập nhật từ điển không gian tên của mô-đun, e. g. ,
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule92 tương đương với
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule93
Thuộc tính được xác định trước [có thể ghi]
Tên của mô-đun
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule09Chuỗi tài liệu của mô-đun hoặc
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 nếu không cóTên đường dẫn của tệp mà mô-đun được tải từ đó, nếu nó được tải từ một tệp. Thuộc tính có thể bị thiếu đối với một số loại mô-đun, chẳng hạn như mô-đun C được liên kết tĩnh vào trình thông dịch. Đối với các mô-đun mở rộng được tải động từ thư viện dùng chung, đó là tên đường dẫn của tệp thư viện dùng chung
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule23Một từ điển chứa được thu thập trong quá trình thực thi thân mô-đun. Để biết các phương pháp hay nhất khi làm việc với
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule23, vui lòng xem
Thuộc tính chỉ đọc đặc biệt. là không gian tên của mô-đun như một đối tượng từ điển
Chi tiết triển khai CPython. Do cách CPython xóa từ điển mô-đun, từ điển mô-đun sẽ bị xóa khi mô-đun nằm ngoài phạm vi ngay cả khi từ điển vẫn có tham chiếu trực tiếp. Để tránh điều này, hãy sao chép từ điển hoặc giữ nguyên mô-đun trong khi sử dụng trực tiếp từ điển của nó
lớp tùy chỉnhCác loại lớp tùy chỉnh thường được tạo bởi các định nghĩa lớp [xem phần ]. Một lớp có một không gian tên được triển khai bởi một đối tượng từ điển. Tham chiếu thuộc tính lớp được dịch sang tra cứu trong từ điển này, e. g. ,
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass02 được dịch thành
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass03 [mặc dù có một số câu móc cho phép các phương tiện định vị thuộc tính khác]. Khi không tìm thấy tên thuộc tính ở đó, việc tìm kiếm thuộc tính tiếp tục trong các lớp cơ sở. Tìm kiếm các lớp cơ sở này sử dụng thứ tự phân giải phương thức C3 hoạt động chính xác ngay cả khi có cấu trúc thừa kế 'kim cương' nơi có nhiều đường dẫn thừa kế dẫn trở lại tổ tiên chung. Chi tiết bổ sung về C3 MRO được sử dụng bởi Python có thể được tìm thấy trong tài liệu đi kèm với 2. 3 phát hành tại https. //www. con trăn. org/tải xuống/phát hành/2. 3/mro/
Khi một tham chiếu thuộc tính lớp [đối với lớp
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule43, chẳng hạn] sẽ tạo ra một đối tượng phương thức lớp, thì nó được chuyển đổi thành một đối tượng phương thức thể hiện có thuộc tính
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule29 là
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule43. Khi nó tạo ra một đối tượng phương thức tĩnh, nó được chuyển đổi thành đối tượng được bao bọc bởi đối tượng phương thức tĩnh. Xem phần này để biết cách khác mà các thuộc tính được truy xuất từ một lớp có thể khác với các thuộc tính thực sự chứa trong lớp đó.
Các phép gán thuộc tính lớp cập nhật từ điển của lớp, không bao giờ là từ điển của lớp cơ sở
Một đối tượng lớp có thể được gọi [xem ở trên] để tạo ra một thể hiện của lớp [xem bên dưới]
thuộc tính đặc biệt
thể hiện lớptên lớp
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule13Tên của mô-đun trong đó lớp được định nghĩa
Từ điển chứa không gian tên của lớp
Một bộ chứa các lớp cơ sở, theo thứ tự xuất hiện của chúng trong danh sách lớp cơ sở
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule09Chuỗi tài liệu của lớp, hoặc
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 nếu không xác địnhimport sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule23Một từ điển chứa được thu thập trong quá trình thực thi nội dung lớp. Để biết các phương pháp hay nhất khi làm việc với
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule23, vui lòng xem
Một thể hiện của lớp được tạo bằng cách gọi một đối tượng lớp [xem bên trên]. Một thể hiện của lớp có một không gian tên được triển khai dưới dạng từ điển, đây là nơi đầu tiên mà các tham chiếu thuộc tính được tìm kiếm. Khi một thuộc tính không được tìm thấy ở đó và lớp của đối tượng có một thuộc tính theo tên đó, quá trình tìm kiếm sẽ tiếp tục với các thuộc tính của lớp. Nếu một thuộc tính lớp được tìm thấy là một đối tượng hàm do người dùng định nghĩa, nó sẽ được chuyển đổi thành một đối tượng phương thức thể hiện có thuộc tính
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule29 là thể hiện. Các đối tượng phương thức tĩnh và phương thức lớp cũng được chuyển đổi; . Xem phần này để biết cách khác mà các thuộc tính của một lớp được truy xuất thông qua các thể hiện của nó có thể khác với các đối tượng thực sự được lưu trữ trong lớp đó. Nếu không tìm thấy thuộc tính lớp nào và lớp của đối tượng có một phương thức, phương thức đó được gọi để đáp ứng việc tra cứu
Việc gán và xóa thuộc tính cập nhật từ điển của cá thể, không bao giờ là từ điển của lớp. Nếu lớp có phương thức hoặc, thì phương thức này được gọi thay vì cập nhật trực tiếp từ điển cá thể
Các thể hiện của lớp có thể giả vờ là số, trình tự hoặc ánh xạ nếu chúng có các phương thức với một số tên đặc biệt. xem phần
thuộc tính đặc biệt. là từ điển thuộc tính;
Đối tượng I/O [còn được gọi là đối tượng tệp]A đại diện cho một tệp đang mở. Nhiều phím tắt có sẵn để tạo các đối tượng tệp. chức năng tích hợp sẵn, cũng như , và phương thức của các đối tượng ổ cắm [và có lẽ bởi các chức năng hoặc phương thức khác được cung cấp bởi các mô-đun mở rộng]
Các đối tượng
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass27,
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass28 và
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass29 được khởi tạo để tạo các đối tượng tệp tương ứng với các luồng đầu vào, đầu ra và lỗi tiêu chuẩn của trình thông dịch; các loại nội bộ
Một vài loại được trình thông dịch sử dụng nội bộ được hiển thị cho người dùng. Định nghĩa của chúng có thể thay đổi với các phiên bản tương lai của trình thông dịch, nhưng chúng được đề cập ở đây cho đầy đủ
đối tượng mãCác đối tượng mã đại diện cho mã Python thực thi được biên dịch theo byte hoặc. Sự khác biệt giữa đối tượng mã và đối tượng hàm là đối tượng hàm chứa tham chiếu rõ ràng đến toàn cục của hàm [mô-đun trong đó nó được xác định], trong khi đối tượng mã không chứa ngữ cảnh; . Không giống như các đối tượng chức năng, các đối tượng mã là bất biến và không chứa tham chiếu [trực tiếp hoặc gián tiếp] đến các đối tượng có thể thay đổi
Thuộc tính chỉ đọc đặc biệt.
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass31 đưa ra tên hàm;
Các bit cờ sau đây được xác định cho
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass47. bit
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass49 được đặt nếu hàm sử dụng cú pháp
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass50 để chấp nhận số lượng đối số vị trí tùy ý;
Các khai báo tính năng trong tương lai [
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass54] cũng sử dụng các bit trong
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass47 để cho biết liệu một đối tượng mã có được biên dịch với một tính năng cụ thể được bật hay không. bit
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass56 được đặt nếu hàm được biên dịch với phép chia trong tương lai được kích hoạt;
Other bits in
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass47 are reserved for internal use
Nếu một đối tượng mã đại diện cho một chức năng, mục đầu tiên trong
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass41 là chuỗi tài liệu của chức năng hoặc
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 nếu không xác địnhđối tượng mã. co_positions[]
Trả về một lần lặp qua các vị trí mã nguồn của mỗi lệnh mã byte trong đối tượng mã
Trình vòng lặp trả về các bộ chứa
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass62. Bộ thứ i tương ứng với vị trí của mã nguồn được biên dịch theo lệnh thứ i. Thông tin cột là độ lệch byte utf-8 được lập chỉ mục 0 trên dòng nguồn đã cho
Thông tin vị trí này có thể bị thiếu. Danh sách không đầy đủ các trường hợp điều này có thể xảy ra
Chạy trình thông dịch với
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass
64Đang tải tệp pyc được biên dịch trong khi sử dụng
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass
64Vị trí các bộ dữ liệu tương ứng với các hướng dẫn nhân tạo
Số dòng và số cột không thể được biểu diễn do giới hạn triển khai cụ thể
Khi điều này xảy ra, một số hoặc tất cả các phần tử của bộ dữ liệu có thể được
Mới trong phiên bản 3. 11
Ghi chú
Tính năng này yêu cầu lưu trữ các vị trí cột trong các đối tượng mã, điều này có thể dẫn đến việc tăng nhẹ mức sử dụng đĩa của các tệp Python đã biên dịch hoặc mức sử dụng bộ nhớ trình thông dịch. Để tránh lưu trữ thông tin bổ sung và/hoặc hủy kích hoạt in thông tin truy nguyên bổ sung, có thể sử dụng cờ dòng lệnh
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass64 hoặc biến môi trườngĐối tượng khung
Các đối tượng khung đại diện cho các khung thực thi. Chúng có thể xảy ra trong các đối tượng theo dõi [xem bên dưới] và cũng được chuyển đến các chức năng theo dõi đã đăng ký
Thuộc tính chỉ đọc đặc biệt.
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass71 is to the previous stack frame [towards the caller], or
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 if this is the bottom stack frame;
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass73 is the code object being executed in this frame;
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass74 is the dictionary used to look up local variables;
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass75 is used for global variables;
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass76 is used for built-in [intrinsic] names;
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass77 gives the precise instruction [this is an index into the bytecode string of the code object]
Việc truy cập vào
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass73 sẽ tạo ra một
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass79 với các đối số
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass80 và
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass81
Thuộc tính có thể ghi đặc biệt.
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass82, nếu không phải là
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8, là một hàm được gọi cho các sự kiện khác nhau trong quá trình thực thi mã [cái này được trình gỡ lỗi sử dụng]. Thông thường, một sự kiện được kích hoạt cho mỗi dòng nguồn mới - điều này có thể bị vô hiệu hóa bằng cách đặt
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass84 thành
Việc triển khai có thể cho phép yêu cầu các sự kiện trên mỗi mã hành động bằng cách đặt
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass86 thành. Lưu ý rằng điều này có thể dẫn đến hành vi trình thông dịch không xác định nếu các ngoại lệ do hàm theo dõi đưa ra thoát đến hàm đang được theo dõi
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass88 là số dòng hiện tại của khung — ghi vào dòng này từ bên trong hàm theo dõi nhảy đến dòng đã cho [chỉ dành cho khung dưới cùng]. Trình gỡ lỗi có thể triển khai lệnh Nhảy [còn gọi là Đặt câu lệnh tiếp theo] bằng cách ghi vào f_lineno
Các đối tượng khung hỗ trợ một phương thức
khung hình. xóa[]Phương pháp này xóa tất cả các tham chiếu đến các biến cục bộ được giữ bởi khung. Ngoài ra, nếu khung thuộc về trình tạo, trình tạo được hoàn thiện. Điều này giúp phá vỡ các chu kỳ tham chiếu liên quan đến các đối tượng khung [ví dụ: khi bắt một ngoại lệ và lưu trữ dấu vết của nó để sử dụng sau này]
được nâng lên nếu khung hiện đang thực thi
Mới trong phiên bản 3. 4
đối tượng truy nguyênCác đối tượng truy nguyên đại diện cho một dấu vết ngăn xếp của một ngoại lệ. Một đối tượng truy nguyên được tạo hoàn toàn khi xảy ra ngoại lệ và cũng có thể được tạo rõ ràng bằng cách gọi
For implicitly created tracebacks, when the search for an exception handler unwinds the execution stack, at each unwound level a traceback object is inserted in front of the current traceback. Khi một trình xử lý ngoại lệ được nhập, dấu vết ngăn xếp sẽ được cung cấp cho chương trình. [Xem phần. ] Nó có thể truy cập dưới dạng mục thứ ba của bộ được trả về bởi
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass91 và là thuộc tính
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass92 của ngoại lệ bị bắt
Khi chương trình không chứa trình xử lý phù hợp, dấu vết ngăn xếp được ghi [được định dạng độc đáo] vào luồng lỗi tiêu chuẩn;
Đối với các dấu vết được tạo rõ ràng, người tạo dấu vết phải xác định cách liên kết các thuộc tính
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass94 để tạo thành một dấu vết ngăn xếp đầy đủ
Thuộc tính chỉ đọc đặc biệt.
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass95 điểm vào khung thi hành của mức hiện tại; . Số dòng và lệnh cuối cùng trong truy nguyên có thể khác với số dòng của đối tượng khung của nó nếu ngoại lệ xảy ra trong một câu lệnh không có mệnh đề ngoại trừ phù hợp hoặc với mệnh đề cuối cùng
Truy cập vào
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass95 sẽ tạo ra một
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass79 với các đối số
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass80 và
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']02
Thuộc tính có thể ghi đặc biệt.
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass94 là cấp độ tiếp theo trong theo dõi ngăn xếp [đối với khung nơi xảy ra ngoại lệ] hoặc
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 nếu không có cấp độ tiếp theo
Changed in version 3. 7. Các đối tượng truy ngược giờ đây có thể được khởi tạo rõ ràng từ mã Python và thuộc tính
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass94 của các phiên bản hiện có có thể được cập nhật. Cắt đối tượng
Các đối tượng lát cắt được sử dụng để biểu diễn các lát cắt cho các phương thức. Chúng cũng được tạo bởi chức năng tích hợp
Thuộc tính chỉ đọc đặc biệt.
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']08 là giới hạn dưới; . These attributes can have any type
Slice objects support one method
slice. indices[self , length]This method takes a single integer argument length and computes information about the slice that the slice object would describe if applied to a sequence of length items. It returns a tuple of three integers; respectively these are the start and stop indices and the step or stride length of the slice. Missing or out-of-bounds indices are handled in a manner consistent with regular slices
Static method objectsStatic method objects provide a way of defeating the transformation of function objects to method objects described above. A static method object is a wrapper around any other object, usually a user-defined method object. When a static method object is retrieved from a class or a class instance, the object actually returned is the wrapped object, which is not subject to any further transformation. Static method objects are also callable. Static method objects are created by the built-in constructor
Class method objectsA class method object, like a static method object, is a wrapper around another object that alters the way in which that object is retrieved from classes and class instances. The behaviour of class method objects upon such retrieval is described above, under “User-defined methods”. Class method objects are created by the built-in constructor
3. 3. Special method names
A class can implement certain operations that are invoked by special syntax [such as arithmetic operations or subscripting and slicing] by defining methods with special names. This is Python’s approach to operator overloading, allowing classes to define their own behavior with respect to language operators. For instance, if a class defines a method named , and
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass0 is an instance of this class, then
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']16 is roughly equivalent to
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']17. Except where mentioned, attempts to execute an operation raise an exception when no appropriate method is defined [typically or ]
Setting a special method to
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 indicates that the corresponding operation is not available. For example, if a class sets to
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8, the class is not iterable, so calling on its instances will raise a [without falling back to ].
When implementing a class that emulates any built-in type, it is important that the emulation only be implemented to the degree that it makes sense for the object being modelled. For example, some sequences may work well with retrieval of individual elements, but extracting a slice may not make sense. [One example of this is the
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']26 interface in the W3C’s Document Object Model. ]
3. 3. 1. Basic customization
object. __new__[cls[ , . ]]Called to create a new instance of class cls. is a static method [special-cased so you need not declare it as such] that takes the class of which an instance was requested as its first argument. The remaining arguments are those passed to the object constructor expression [the call to the class]. The return value of should be the new object instance [usually an instance of cls]
Typical implementations create a new instance of the class by invoking the superclass’s method using
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']30 with appropriate arguments and then modifying the newly created instance as necessary before returning it
If is invoked during object construction and it returns an instance of cls, then the new instance’s method will be invoked like
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']33, where self is the new instance and the remaining arguments are the same as were passed to the object constructor
If does not return an instance of cls, then the new instance’s method will not be invoked
is intended mainly to allow subclasses of immutable types [like int, str, or tuple] to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation
object. __init__[self[ , . ]]Called after the instance has been created [by ], but before it is returned to the caller. The arguments are those passed to the class constructor expression. If a base class has an method, the derived class’s method, if any, must explicitly call it to ensure proper initialization of the base class part of the instance; for example.
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']40
Because and work together in constructing objects [ to create it, and to customize it], no non-
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 value may be returned by ; doing so will cause a to be raised at runtimeobject. __del__[self]
Được gọi khi instance sắp bị hủy. This is also called a finalizer or [improperly] a destructor. If a base class has a method, the derived class’s method, if any, must explicitly call it to ensure proper deletion of the base class part of the instance
It is possible [though not recommended. ] for the method to postpone destruction of the instance by creating a new reference to it. This is called object resurrection. It is implementation-dependent whether is called a second time when a resurrected object is about to be destroyed; the current implementation only calls it once
It is not guaranteed that methods are called for objects that still exist when the interpreter exits
Ghi chú
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']53 doesn’t directly call
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']54 — the former decrements the reference count for
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass0 by one, and the latter is only called when
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass0’s reference count reaches zero
CPython implementation detail. It is possible for a reference cycle to prevent the reference count of an object from going to zero. In this case, the cycle will be later detected and deleted by the . A common cause of reference cycles is when an exception has been caught in a local variable. The frame’s locals then reference the exception, which references its own traceback, which references the locals of all frames caught in the traceback
See also
Documentation for the module
Warning
Do các trường hợp bấp bênh mà theo đó các phương thức được gọi, các ngoại lệ xảy ra trong quá trình thực thi chúng sẽ bị bỏ qua và thay vào đó, một cảnh báo sẽ được in tới
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass29. In particular
can be invoked when arbitrary code is being executed, including from any arbitrary thread. If needs to take a lock or invoke any other blocking resource, it may deadlock as the resource may already be taken by the code that gets interrupted to execute
can be executed during interpreter shutdown. Do đó, các biến toàn cục mà nó cần truy cập [bao gồm cả các mô-đun khác] có thể đã bị xóa hoặc được đặt thành
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']
8. Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; if no other references to such globals exist, this may help in assuring that imported modules are still available at the time when the method is called
Called by the built-in function to compute the “official” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value [given an appropriate environment]. If this is not possible, a string of the form
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']67 should be returned. The return value must be a string object. If a class defines but not , then is also used when an “informal” string representation of instances of that class is required
This is typically used for debugging, so it is important that the representation is information-rich and unambiguous
object. __str__[self]Called by and the built-in functions and to compute the “informal” or nicely printable string representation of an object. The return value must be a object
This method differs from in that there is no expectation that return a valid Python expression. a more convenient or concise representation can be used
The default implementation defined by the built-in type calls
object. __bytes__[self]Called by to compute a byte-string representation of an object. This should return a object
object. __format__[self , format_spec]Called by the built-in function, and by extension, evaluation of and the method, to produce a “formatted” string representation of an object. The format_spec argument is a string that contains a description of the formatting options desired. The interpretation of the format_spec argument is up to the type implementing , however most classes will either delegate formatting to one of the built-in types, or use a similar formatting option syntax
See for a description of the standard formatting syntax
The return value must be a string object
Changed in version 3. 4. The __format__ method of
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']76 itself raises a if passed any non-empty string.
Changed in version 3. 7.
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']84 is now equivalent to
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']85 rather than
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']86. object. __lt__[self , other]object. __le__[self , other]object. __eq__[self , other]object. __ne__[self , other]object. __gt__[self , other]object. __ge__[self , other]
These are the so-called “rich comparison” methods. The correspondence between operator symbols and method names is as follows.
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']87 calls
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']88,
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']89 calls
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']90,
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']91 calls
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']92,
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']93 calls
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']94,
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']95 calls
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']96, and
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']97 calls
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']98
A rich comparison method may return the singleton
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']9 if it does not implement the operation for a given pair of arguments. By convention,
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass1 and
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass2 are returned for a successful comparison. However, these methods can return any value, so if the comparison operator is used in a Boolean context [e. g. , in the condition of an
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook02 statement], Python will call on the value to determine if the result is true or false
By default,
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']76 implements by using
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule7, returning
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']9 in the case of a false comparison.
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook08. For , by default it delegates to and inverts the result unless it is
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']9. There are no other implied relationships among the comparison operators or default implementations; for example, the truth of
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook12 does not imply
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']89. To automatically generate ordering operations from a single root operation, see
See the paragraph on for some important notes on creating objects which support custom comparison operations and are usable as dictionary keys
There are no swapped-argument versions of these methods [to be used when the left argument does not support the operation but the right argument does]; rather, and are each other’s reflection, and are each other’s reflection, and and are their own reflection. If the operands are of different types, and right operand’s type is a direct or indirect subclass of the left operand’s type, the reflected method of the right operand has priority, otherwise the left operand’s method has priority. Virtual subclassing is not considered
object. __hash__[self]Called by built-in function and for operations on members of hashed collections including , , and . The
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook15 method should return an integer. The only required property is that objects which compare equal have the same hash value; it is advised to mix together the hash values of the components of the object that also play a part in comparison of objects by packing them into a tuple and hashing the tuple. Example
def __hash__[self]: return hash[[self.name, self.nick, self.color]]
Ghi chú
truncates the value returned from an object’s custom method to the size of a . This is typically 8 bytes on 64-bit builds and 4 bytes on 32-bit builds. If an object’s must interoperate on builds of different bit sizes, be sure to check the width on all supported builds. An easy way to do this is with
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook31
If a class does not define an method it should not define a operation either; if it defines but not , its instances will not be usable as items in hashable collections. If a class defines mutable objects and implements an method, it should not implement , since the implementation of hashable collections requires that a key’s hash value is immutable [if the object’s hash value changes, it will be in the wrong hash bucket]
User-defined classes have and methods by default; with them, all objects compare unequal [except with themselves] and
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook40 returns an appropriate value such that
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook41 implies both that
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook42 and
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook43
A class that overrides and does not define will have its implicitly set to
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8. When the method of a class is
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8, instances of the class will raise an appropriate when a program attempts to retrieve their hash value, and will also be correctly identified as unhashable when checking
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook51
If a class that overrides needs to retain the implementation of from a parent class, the interpreter must be told this explicitly by setting
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook54
If a class that does not override wishes to suppress hash support, it should include
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook56 in the class definition. A class which defines its own that explicitly raises a would be incorrectly identified as hashable by an
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook51 call
Ghi chú
By default, the values of str and bytes objects are “salted” with an unpredictable random value. Although they remain constant within an individual Python process, they are not predictable between repeated invocations of Python
This is intended to provide protection against a denial-of-service caused by carefully chosen inputs that exploit the worst case performance of a dict insertion, O[n2] complexity. See http. //www. ocert. org/advisories/ocert-2011-003. html for details
Changing hash values affects the iteration order of sets. Python has never made guarantees about this ordering [and it typically varies between 32-bit and 64-bit builds]
See also
Changed in version 3. 3. Hash randomization is enabled by default.
object. __bool__[self]Called to implement truth value testing and the built-in operation
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook03; should return
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass1 or
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass2. When this method is not defined, is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither nor , all its instances are considered true
3. 3. 2. Customizing attribute access
The following methods can be defined to customize the meaning of attribute access [use of, assignment to, or deletion of
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook68] for class instancesobject. __getattr__[self , name]
Called when the default attribute access fails with an [either raises an because name is not an instance attribute or an attribute in the class tree for
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook72; or of a name property raises ]. This method should either return the [computed] attribute value or raise an exception
Note that if the attribute is found through the normal mechanism, is not called. [Đây là sự bất đối xứng có chủ ý giữa và. ] This is done both for efficiency reasons and because otherwise would have no way to access other attributes of the instance. Note that at least for instance variables, you can fake total control by not inserting any values in the instance attribute dictionary [but instead inserting them in another object]. See the method below for a way to actually get total control over attribute access
object. __getattribute__[self , name]Called unconditionally to implement attribute accesses for instances of the class. Nếu lớp cũng định nghĩa, thì lớp sau sẽ không được gọi trừ khi gọi nó một cách rõ ràng hoặc đưa ra một. This method should return the [computed] attribute value or raise an exception. In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example,
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook85
Ghi chú
This method may still be bypassed when looking up special methods as the result of implicit invocation via language syntax or built-in functions. See
For certain sensitive attribute accesses, raises an
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass79 with arguments
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass80 and
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook88object. __setattr__[self , name , value]
Được gọi khi thử gán thuộc tính. This is called instead of the normal mechanism [i. e. store the value in the instance dictionary]. name is the attribute name, value is the value to be assigned to it
If wants to assign to an instance attribute, it should call the base class method with the same name, for example,
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook90
For certain sensitive attribute assignments, raises an
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook91 with arguments
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass80,
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook88,
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook94
Thích nhưng để xóa thuộc tính thay vì gán. This should only be implemented if
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook96 is meaningful for the object
For certain sensitive attribute deletions, raises an
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook97 with arguments
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass80 and
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook88object. __dir__[self]
Called when is called on the object. A sequence must be returned. converts the returned sequence to a list and sorts it
3. 3. 2. 1. Customizing module attribute access
Special names
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass02 and
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass03 can be also used to customize access to module attributes. The
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass02 function at the module level should accept one argument which is the name of an attribute and return the computed value or raise an . If an attribute is not found on a module object through the normal lookup, i. e. , then
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass02 is searched in the module
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule19 before raising an . If found, it is called with the attribute name and the result is returned
The
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass03 function should accept no arguments, and return a sequence of strings that represents the names accessible on module. If present, this function overrides the standard search on a module
For a more fine grained customization of the module behavior [setting attributes, properties, etc. ], one can set the
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass22 attribute of a module object to a subclass of . For example
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule
Ghi chú
Defining module
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass02 and setting module
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass22 only affect lookups made using the attribute access syntax – directly accessing the module globals [whether by code within the module, or via a reference to the module’s globals dictionary] is unaffected
Changed in version 3. 5.
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass22 module attribute is now writable.
New in version 3. 7.
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass02 and
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass03 module attributes.
See also
PEP 562 - Module __getattr__ and __dir__Describes the
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass02 and
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass03 functions on modules
3. 3. 2. 2. Implementing Descriptors
The following methods only apply when an instance of the class containing the method [a so-called descriptor class] appears in an owner class [the descriptor must be in either the owner’s class dictionary or in the class dictionary for one of its parents]. In the examples below, “the attribute” refers to the attribute whose name is the key of the property in the owner class’
object. __get__[self , instance , owner=None]Called to get the attribute of the owner class [class attribute access] or of an instance of that class [instance attribute access]. The optional owner argument is the owner class, while instance is the instance that the attribute was accessed through, or
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 when the attribute is accessed through the owner
This method should return the computed attribute value or raise an exception
PEP 252 specifies that is callable with one or two arguments. Python’s own built-in descriptors support this specification; however, it is likely that some third-party tools have descriptors that require both arguments. Python’s own implementation always passes in both arguments whether they are required or not
object. __set__[self , instance , value]Called to set the attribute on an instance instance of the owner class to a new value, value
Note, adding or changes the kind of descriptor to a “data descriptor”. See for more details
object. __delete__[self , instance]Called to delete the attribute on an instance instance of the owner class
The attribute
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass28 is interpreted by the module as specifying the class where this object was defined [setting this appropriately can assist in runtime introspection of dynamic class attributes]. For callables, it may indicate that an instance of the given type [or a subclass] is expected or required as the first positional argument [for example, CPython sets this attribute for unbound methods that are implemented in C]
3. 3. 2. 3. Invoking Descriptors
In general, a descriptor is an object attribute with “binding behavior”, one whose attribute access has been overridden by methods in the descriptor protocol. , , and . If any of those methods are defined for an object, it is said to be a descriptor
The default behavior for attribute access is to get, set, or delete the attribute from an object’s dictionary. For instance,
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass33 has a lookup chain starting with
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass34, then
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass35, and continuing through the base classes of
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass36 excluding metaclasses
However, if the looked-up value is an object defining one of the descriptor methods, then Python may override the default behavior and invoke the descriptor method instead. Where this occurs in the precedence chain depends on which descriptor methods were defined and how they were called
The starting point for descriptor invocation is a binding,
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass33. How the arguments are assembled depends on
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']0Direct Call
The simplest and least common call is when user code directly invokes a descriptor method.
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass39Instance Binding
If binding to an object instance,
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass33 is transformed into the call.
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass41Class Binding
If binding to a class,
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass42 is transformed into the call.
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass43Super Binding
A dotted lookup such as
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass44 searches
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass45 for a base class
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass46 following
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass47 and then returns
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass48. If not a descriptor,
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass0 is returned unchanged
For instance bindings, the precedence of descriptor invocation depends on which descriptor methods are defined. A descriptor can define any combination of , and . If it does not define
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook73, then accessing the attribute will return the descriptor object itself unless there is a value in the object’s instance dictionary. If the descriptor defines
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass26 and/or
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass27, it is a data descriptor; if it defines neither, it is a non-data descriptor. Normally, data descriptors define both
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook73 and
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass26, while non-data descriptors have just the
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook73 method. Data descriptors with
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook73 and
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass26 [and/or
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass27] defined always override a redefinition in an instance dictionary. In contrast, non-data descriptors can be overridden by instances
Python methods [including those decorated with and ] are implemented as non-data descriptors. Accordingly, instances can redefine and override methods. This allows individual instances to acquire behaviors that differ from other instances of the same class
The function is implemented as a data descriptor. Accordingly, instances cannot override the behavior of a property
3. 3. 2. 4. __slots__
__slots__ allow us to explicitly declare data members [like properties] and deny the creation of and __weakref__ [unless explicitly declared in __slots__ or available in a parent. ]
The space saved over using can be significant. Attribute lookup speed can be significantly improved as well
object. __slots__This class variable can be assigned a string, iterable, or sequence of strings with variable names used by instances. __slots__ reserves space for the declared variables and prevents the automatic creation of and __weakref__ for each instance
When inheriting from a class without __slots__, the and __weakref__ attribute of the instances will always be accessible
Without a variable, instances cannot be assigned new variables not listed in the __slots__ definition. Attempts to assign to an unlisted variable name raises . If dynamic assignment of new variables is desired, then add
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass
71 to the sequence of strings in the __slots__ declarationWithout a __weakref__ variable for each instance, classes defining __slots__ do not support to its instances. If weak reference support is needed, then add
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass
73 to the sequence of strings in the __slots__ declaration__slots__ are implemented at the class level by creating for each variable name. As a result, class attributes cannot be used to set default values for instance variables defined by __slots__; otherwise, the class attribute would overwrite the descriptor assignment
The action of a __slots__ declaration is not limited to the class where it is defined. __slots__ declared in parents are available in child classes. However, child subclasses will get a and __weakref__ unless they also define __slots__ [which should only contain names of any additional slots]
If a class defines a slot also defined in a base class, the instance variable defined by the base class slot is inaccessible [except by retrieving its descriptor directly from the base class]. This renders the meaning of the program undefined. In the future, a check may be added to prevent this
Nonempty __slots__ does not work for classes derived from “variable-length” built-in types such as , and
Any non-string may be assigned to __slots__
If a is used to assign __slots__, the dictionary keys will be used as the slot names. The values of the dictionary can be used to provide per-attribute docstrings that will be recognised by and displayed in the output of
assignment works only if both classes have the same __slots__
with multiple slotted parent classes can be used, but only one parent is allowed to have attributes created by slots [the other bases must have empty slot layouts] - violations raise
If an is used for __slots__ then a is created for each of the iterator’s values. However, the __slots__ attribute will be an empty iterator
3. 3. 3. Customizing class creation
Whenever a class inherits from another class, is called on the parent class. This way, it is possible to write classes which change the behavior of subclasses. This is closely related to class decorators, but where class decorators only affect the specific class they’re applied to,
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass84 solely applies to future subclasses of the class defining the methodphương thức lớp đối tượng. __init_subclass__[cls]
Phương thức này được gọi bất cứ khi nào lớp chứa được phân lớp. cls sau đó là phân lớp mới. If defined as a normal instance method, this method is implicitly converted to a class method
Keyword arguments which are given to a new class are passed to the parent’s class
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass84. For compatibility with other classes using
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass84, one should take out the needed keyword arguments and pass the others over to the base class, as in
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass
The default implementation
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass87 does nothing, but raises an error if it is called with any arguments
Ghi chú
The metaclass hint
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass88 is consumed by the rest of the type machinery, and is never passed to
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass84 implementations. The actual metaclass [rather than the explicit hint] can be accessed as
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass90
New in version 3. 6
When a class is created,
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass91 scans the class variables and makes callbacks to those with a hookobject. __set_name__[self , owner , name]
Automatically called at the time the owning class owner is created. The object has been assigned to name in that class
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']
If the class variable is assigned after the class is created, will not be called automatically. If needed, can be called directly
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook
See for more details
New in version 3. 6
3. 3. 3. 1. Metaclasses
By default, classes are constructed using . The class body is executed in a new namespace and the class name is bound locally to the result of
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass96
The class creation process can be customized by passing the
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass88 keyword argument in the class definition line, or by inheriting from an existing class that included such an argument. In the following example, both
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass98 and
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass99 are instances of
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]00
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass
Any other keyword arguments that are specified in the class definition are passed through to all metaclass operations described below
When a class definition is executed, the following steps occur
MRO entries are resolved;
the appropriate metaclass is determined;
the class namespace is prepared;
the class body is executed;
the class object is created
3. 3. 3. 2. Resolving MRO entries
If a base that appears in class definition is not an instance of , then an
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]02 method is searched on it. If found, it is called with the original bases tuple. This method must return a tuple of classes that will be used instead of this base. The tuple may be empty, in such case the original base is ignored
See also
PEP 560 - Core support for typing module and generic types
3. 3. 3. 3. Determining the appropriate metaclass
The appropriate metaclass for a class definition is determined as follows
if no bases and no explicit metaclass are given, then is used;
if an explicit metaclass is given and it is not an instance of , then it is used directly as the metaclass;
if an instance of is given as the explicit metaclass, or bases are defined, then the most derived metaclass is used
The most derived metaclass is selected from the explicitly specified metaclass [if any] and the metaclasses [i. e.
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass90] of all specified base classes. The most derived metaclass is one which is a subtype of all of these candidate metaclasses. If none of the candidate metaclasses meets that criterion, then the class definition will fail with
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook2
3. 3. 3. 4. Preparing the class namespace
Once the appropriate metaclass has been identified, then the class namespace is prepared. If the metaclass has a
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]08 attribute, it is called as
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]09 [where the additional keyword arguments, if any, come from the class definition]. The
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]08 method should be implemented as a . The namespace returned by
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]08 is passed in to
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]13, but when the final class object is created the namespace is copied into a new
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook25
If the metaclass has no
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]08 attribute, then the class namespace is initialised as an empty ordered mapping
See also
PEP 3115 - Metaclasses in Python 3000Introduced the
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]08 namespace hook
3. 3. 3. 5. Executing the class body
The class body is executed [approximately] as
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]17. The key difference from a normal call to is that lexical scoping allows the class body [including any methods] to reference names from the current and outer scopes when the class definition occurs inside a function
However, even when the class definition occurs inside the function, methods defined inside the class still cannot see names defined at the class scope. Class variables must be accessed through the first parameter of instance or class methods, or through the implicit lexically scoped
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass22 reference described in the next section
3. 3. 3. 6. Creating the class object
Once the class namespace has been populated by executing the class body, the class object is created by calling
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]20 [the additional keywords passed here are the same as those passed to
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]08]
This class object is the one that will be referenced by the zero-argument form of .
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass22 is an implicit closure reference created by the compiler if any methods in a class body refer to either
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass22 or
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]25. This allows the zero argument form of to correctly identify the class being defined based on lexical scoping, while the class or instance that was used to make the current call is identified based on the first argument passed to the method
CPython implementation detail. In CPython 3. 6 trở lên, ô
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass22 được chuyển đến siêu dữ liệu dưới dạng mục nhập
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]28 trong không gian tên lớp. If present, this must be propagated up to the
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]29 call in order for the class to be initialised correctly. Failing to do so will result in a in Python 3. 8
When using the default metaclass , or any metaclass that ultimately calls
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]29, the following additional customization steps are invoked after creating the class object
The
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]
29 method collects all of the attributes in the class namespace that define a method;Those
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]
35 methods are called with the class being defined and the assigned name of that particular attribute;The hook is called on the immediate parent of the new class in its method resolution order
After the class object is created, it is passed to the class decorators included in the class definition [if any] and the resulting object is bound in the local namespace as the defined class
When a new class is created by
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]29, the object provided as the namespace parameter is copied to a new ordered mapping and the original object is discarded. The new copy is wrapped in a read-only proxy, which becomes the attribute of the class object
See also
PEP 3135 - New superDescribes the implicit
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass22 closure reference
3. 3. 3. 7. Uses for metaclasses
The potential uses for metaclasses are boundless. Some ideas that have been explored include enum, logging, interface checking, automatic delegation, automatic property creation, proxies, frameworks, and automatic resource locking/synchronization
3. 3. 4. Customizing instance and subclass checks
The following methods are used to override the default behavior of the and built-in functions
In particular, the metaclass implements these methods in order to allow the addition of Abstract Base Classes [ABCs] as “virtual base classes” to any class or type [including built-in types], including other ABCs
class. __instancecheck__[self , instance]Return true if instance should be considered a [direct or indirect] instance of class. If defined, called to implement
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]43class. __subclasscheck__[self , subclass]
Return true if subclass should be considered a [direct or indirect] subclass of class. If defined, called to implement
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]44
Note that these methods are looked up on the type [metaclass] of a class. They cannot be defined as class methods in the actual class. This is consistent with the lookup of special methods that are called on instances, only in this case the instance is itself a class
See also
PEP 3119 - Introducing Abstract Base ClassesIncludes the specification for customizing and behavior through and , with motivation for this functionality in the context of adding Abstract Base Classes [see the module] to the language
3. 3. 5. Emulating generic types
When using , it is often useful to parameterize a using Python’s square-brackets notation. For example, the annotation
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]50 might be used to signify a in which all the elements are of type
See also
PEP 484 - Type HintsIntroducing Python’s framework for type annotations
Documentation for objects representing parameterized generic classes
, vàDocumentation on how to implement generic classes that can be parameterized at runtime and understood by static type-checkers
A class can generally only be parameterized if it defines the special class method
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]54phương thức lớp đối tượng. __class_getitem__[cls , key]
Trả về một đối tượng đại diện cho chuyên môn hóa của một lớp chung bằng các đối số loại được tìm thấy trong khóa
When defined on a class,
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]54 is automatically a class method. Như vậy, không cần phải trang trí nó khi nó được xác định
3. 3. 5. 1. The purpose of __class_getitem__
Mục đích của là cho phép tham số hóa thời gian chạy của các lớp chung trong thư viện chuẩn để dễ dàng áp dụng hơn cho các lớp này
To implement custom generic classes that can be parameterized at runtime and understood by static type-checkers, users should either inherit from a standard library class that already implements , or inherit from , which has its own implementation of
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]54
Việc triển khai tùy chỉnh của các lớp được xác định bên ngoài thư viện chuẩn có thể không được hiểu bởi trình kiểm tra loại của bên thứ ba, chẳng hạn như mypy. Không khuyến khích sử dụng
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]54 trên bất kỳ lớp nào cho các mục đích khác ngoài gợi ý loại
3. 3. 5. 2. __class_getitem__ so với __getitem__
Thông thường, đối tượng sử dụng dấu ngoặc vuông sẽ gọi phương thức thể hiện được xác định trên lớp của đối tượng. Tuy nhiên, nếu đối tượng được đăng ký chính là một lớp, phương thức lớp có thể được gọi thay thế.
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]54 sẽ trả về một đối tượng nếu nó được xác định đúng
Được trình bày với
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]66, trình thông dịch Python tuân theo quy trình giống như quy trình sau để quyết định có nên gọi hay không
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]
Trong Python, tất cả các lớp đều là thể hiện của các lớp khác. Lớp của một lớp được gọi là lớp đó và hầu hết các lớp đều có lớp đó là siêu dữ liệu của chúng. does not define , meaning that expressions such as
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]50,
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]73 and
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]74 all result in being called
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]
However, if a class has a custom metaclass that defines , subscribing the class may result in different behaviour. Một ví dụ về điều này có thể được tìm thấy trong mô-đun
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]
See also
PEP 560 - Hỗ trợ cốt lõi để nhập mô-đun và các loại chungGiới thiệu và phác thảo khi một kết quả trong
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]54 được gọi thay vì
3. 3. 6. Mô phỏng các đối tượng có thể gọi
đối tượng. __call__[bản thân[ , . args...]]Được gọi khi thể hiện được “gọi” là một hàm;
3. 3. 7. Mô phỏng các loại vùng chứa
Các phương thức sau có thể được định nghĩa để triển khai các đối tượng vùng chứa. Các vùng chứa thường là [chẳng hạn như hoặc ] hoặc [như ], nhưng cũng có thể đại diện cho các vùng chứa khác. Tập hợp các phương thức đầu tiên được sử dụng để mô phỏng một chuỗi hoặc để mô phỏng một ánh xạ; . Chúng tôi cũng khuyến nghị rằng các ánh xạ cung cấp các phương thức
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]88,
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]89,
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]90,
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]91,
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]92,
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]93,
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]94,
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]95,
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]96 và
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]97 hoạt động tương tự như đối với các đối tượng tiêu chuẩn của Python. Mô-đun này cung cấp một để giúp tạo các phương thức đó từ một bộ cơ sở gồm , , và
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]88. Mutable sequences should provide methods
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]05,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]06,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]07,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]08,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]09,
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]94,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]11,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]12 and
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]13, like Python standard objects. Cuối cùng, các loại trình tự nên thực hiện phép cộng [nghĩa là nối] và phép nhân [nghĩa là lặp lại] bằng cách xác định các phương thức , , , và được mô tả bên dưới; . It is recommended that both mappings and sequences implement the method to allow efficient use of the
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]22 operator; for mappings,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]22 should search the mapping’s keys; for sequences, it should search through the values. Ngoài ra, chúng tôi khuyến nghị rằng cả ánh xạ và trình tự đều triển khai phương thức để cho phép lặp lại hiệu quả thông qua vùng chứa; đối tượng. __len__[bản thân]
Được gọi để thực hiện chức năng tích hợp. Nên trả về chiều dài của đối tượng, một số nguyên
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]9 0. Ngoài ra, một đối tượng không xác định một phương thức và phương thức của nó trả về 0 được coi là sai trong ngữ cảnh Boolean
CPython implementation detail. Trong CPython, độ dài được yêu cầu tối đa. Nếu chiều dài lớn hơn
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]30, một số tính năng [chẳng hạn như ] có thể tăng. Để ngăn việc tăng
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]33 bằng cách kiểm tra giá trị thực, một đối tượng phải xác định một phương thứcđối tượng. __length_hint__[self]
Kêu gọi thực hiện. Nên trả về độ dài ước tính cho đối tượng [có thể lớn hơn hoặc nhỏ hơn độ dài thực tế]. Độ dài phải là một số nguyên
from inspect import isclass def subscribe[obj, x]: """Return the result of the expression 'obj[x]'""" class_of_obj = type[obj] # If the class of obj defines __getitem__, # call class_of_obj.__getitem__[obj, x] if hasattr[class_of_obj, '__getitem__']: return class_of_obj.__getitem__[obj, x] # Else, if obj is a class and defines __class_getitem__, # call obj.__class_getitem__[x] elif isclass[obj] and hasattr[obj, '__class_getitem__']: return obj.__class_getitem__[x] # Else, raise an exception else: raise TypeError[ f"'{class_of_obj.__name__}' object is not subscriptable" ]9 0. Giá trị trả về cũng có thể là , được xử lý giống như khi phương thức
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]39 hoàn toàn không tồn tại. Phương pháp này hoàn toàn là một tối ưu hóa và không bao giờ cần thiết cho tính chính xác
Mới trong phiên bản 3. 4
Ghi chú
Slicing is done exclusively with the following three methods. Một cuộc gọi như
a[1:2] = b
được dịch sang
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule0
và kể từ đó trở đi. Các mục lát bị thiếu luôn được điền vào bằng
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8đối tượng. __getitem__[self , key]
Được gọi để thực hiện đánh giá của
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]41. Đối với các loại, các khóa được chấp nhận phải là số nguyên và đối tượng lát. Lưu ý rằng cách giải thích đặc biệt của các chỉ mục phủ định [nếu lớp muốn mô phỏng một loại] tùy thuộc vào phương thức. Nếu khóa thuộc loại không phù hợp, có thể được nâng lên; . Đối với các loại nếu thiếu key [không có trong container] thì nên nâng lên
Ghi chú
các vòng lặp mong đợi rằng an sẽ được nâng lên đối với các chỉ mục không hợp lệ để cho phép phát hiện đúng phần cuối của chuỗi
Ghi chú
Khi một lớp, phương thức lớp đặc biệt có thể được gọi thay vì
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']06. See for more detailsđối tượng. __setitem__[bản thân , phím, value]
Được gọi để thực hiện nhiệm vụ cho
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]41. Lưu ý tương tự như đối với. Điều này chỉ nên được thực hiện cho ánh xạ nếu các đối tượng hỗ trợ thay đổi giá trị cho các khóa hoặc nếu có thể thêm các khóa mới hoặc cho các chuỗi nếu các phần tử có thể được thay thế. The same exceptions should be raised for improper key values as for the methodobject. __delitem__[bản thân , phím]
Called to implement deletion of
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]41. Same note as for . This should only be implemented for mappings if the objects support removal of keys, or for sequences if elements can be removed from the sequence. The same exceptions should be raised for improper key values as for the methodobject. __missing__[self , key]
Called by . to implement
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]41 for dict subclasses when key is not in the dictionaryobject. __iter__[self]
This method is called when an is required for a container. This method should return a new iterator object that can iterate over all the objects in the container. For mappings, it should iterate over the keys of the container
object. __reversed__[self]Called [if present] by the built-in to implement reverse iteration. It should return a new iterator object that iterates over all the objects in the container in reverse order
If the method is not provided, the built-in will fall back to using the sequence protocol [ and ]. Objects that support the sequence protocol should only provide if they can provide an implementation that is more efficient than the one provided by
The membership test operators [ and ] are normally implemented as an iteration through a container. However, container objects can supply the following special method with a more efficient implementation, which also does not require the object be iterable
object. __contains__[self , item]Called to implement membership test operators. Should return true if item is in self, false otherwise. For mapping objects, this should consider the keys of the mapping rather than the values or the key-item pairs
For objects that don’t define , the membership test first tries iteration via , then the old sequence iteration protocol via , see
3. 3. 8. Emulating numeric types
The following methods can be defined to emulate numeric objects. Methods corresponding to operations that are not supported by the particular kind of number implemented [e. g. , bitwise operations for non-integral numbers] should be left undefined
object. __add__[self , other]object. __sub__[self , other]object. __mul__[self , other]object. __matmul__[self , other]object. __truediv__[self , other]object. __floordiv__[self , other]object. __mod__[self , other]object. __divmod__[self , other]object. __pow__[self , other[ , modulo]]object. __lshift__[self , other]object. __rshift__[bản thân , khác . ]object.__and__[self , other]object. __xor__[self , other]object. __or__[self , other]Các phương thức này được gọi để thực hiện các phép toán số học nhị phân [
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]71,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]72,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]73,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]74,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]75,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]76,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]77, , ,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]80,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]81,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]82,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]83,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]84,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]85]. Chẳng hạn, để đánh giá biểu thức
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]86, trong đó x là một thể hiện của một lớp có một phương thức,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]88 được gọi. Phương pháp này phải tương đương với việc sử dụng và ; . Lưu ý rằng nên được xác định để chấp nhận đối số thứ ba tùy chọn nếu phiên bản bậc ba của hàm tích hợp được hỗ trợ
Nếu một trong những phương thức đó không hỗ trợ thao tác với các đối số được cung cấp, thì nó sẽ trả về
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']9đối tượng. __radd__[bản thân , khác . ]object.__rsub__[bản thân , khác . ]object.__rmul__[bản thân , khác . ]object.__rmatmul__[bản thân , khác . ]object.__rtruediv__[bản thân , khác . ]object.__rfloordiv__[bản thân , khác . ]object.__rmod__[bản thân , khác . ]object.__rdivmod__[bản thân , khác . ]object.__rpow__[bản thân , khác . [, modulo]]object.__rlshift__[bản thân , khác . ]object.__rrshift__[bản thân , khác . ]object.__rand__[bản thân , khác . ]object.__rxor__[bản thân , khác . ]object.__ror__[bản thân , khác]
Các phương thức này được gọi để thực hiện các phép tính số học nhị phân [
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]71,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]72,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]73,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]74,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]75,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]76,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]77, , ,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]80,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]81,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]82,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]83,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]84,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]85] với toán hạng được phản ánh [đổi chỗ]. Các hàm này chỉ được gọi nếu toán hạng bên trái không hỗ trợ phép toán tương ứng và các toán hạng thuộc các kiểu khác nhau. Chẳng hạn, để đánh giá biểu thức
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]11, trong đó y là một thể hiện của một lớp có một phương thức, ____ _ _ _ _
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]13 được gọi nếu _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Lưu ý rằng ternary sẽ không thử gọi [các quy tắc cưỡng chế sẽ trở nên quá phức tạp]
Ghi chú
Nếu kiểu của toán hạng bên phải là lớp con của kiểu toán hạng bên trái và lớp con đó cung cấp cách triển khai khác của phương thức được phản ánh cho thao tác, thì phương thức này sẽ được gọi trước phương thức không được phản ánh của toán hạng bên trái. Hành vi này cho phép các lớp con ghi đè hoạt động của tổ tiên của chúng
đối tượng. __iadd__[bản thân , khác . ]object.__isub__[bản thân , khác . ]object.__imul__[bản thân , khác . ]object.__imatmul__[bản thân , khác . ]object.__itruediv__[bản thân , khác . ]object.__ifloordiv__[bản thân , khác . ]object.__imod__[bản thân , khác . ]object.__ipow__[bản thân , khác . [, modulo]]object.__ilshift__[bản thân , khác . ]object.__irshift__[bản thân , khác . ]object.__iand__[bản thân , khác . ]object.__ixor__[bản thân , khác . ]object.__ior__[bản thân , khác]Các phương thức này được gọi để thực hiện các bài tập số học tăng cường [
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]17,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]18,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]19,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]20,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]21,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]22,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]23,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]24,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]25,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]26,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]27,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]28,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]29]. These methods should attempt to do the operation in-place [modifying self] and return the result [which could be, but does not have to be, self]. Nếu một phương thức cụ thể không được xác định, phép gán tăng cường sẽ quay trở lại các phương thức thông thường. For instance, if x is an instance of a class with an method,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]31 is equivalent to
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]32 . Mặt khác,
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]33 và
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]34 được xem xét, giống như đánh giá của
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]86. Trong một số trường hợp nhất định, phép gán tăng cường có thể dẫn đến lỗi không mong muốn [xem ], nhưng hành vi này trên thực tế là một phần của mô hình dữ liệuđối tượng. __neg__[bản thân]đối tượng. __pos__[bản thân]đối tượng. __abs__[bản thân]đối tượng. __invert__[bản thân]
Được gọi để thực hiện các phép toán số học đơn vị [
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]72,
>>> # list has class "type" as its metaclass, like most classes: >>> type[list] >>> type[dict] == type[list] == type[tuple] == type[str] == type[bytes] True >>> # "list[int]" calls "list.__class_getitem__[int]" >>> list[int] list[int] >>> # list.__class_getitem__ returns a GenericAlias object: >>> type[list[int]]71, và
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]39]đối tượng. __complex__[bản thân]đối tượng. __int__[bản thân]đối tượng. __float__[bản thân]
Được gọi để triển khai các hàm tích hợp và. Nên trả về một giá trị của loại thích hợp
đối tượng. __index__[bản thân]Được gọi để triển khai và bất cứ khi nào Python cần chuyển đổi dễ dàng đối tượng số thành đối tượng số nguyên [chẳng hạn như trong cắt lát hoặc trong các hàm và tích hợp sẵn]. Sự hiện diện của phương thức này chỉ ra rằng đối tượng số là một kiểu số nguyên. Phải trả về một số nguyên
Nếu và không được xác định thì các hàm tích hợp tương ứng và quay lại
đối tượng. __round__[bản thân[ , . ndigits]]object.__trunc__[bản thân]đối tượng. __floor__[bản thân]đối tượng. __ceil__[bản thân]Được gọi để triển khai chức năng và chức năng tích hợp sẵn, và. Trừ khi ndigits được chuyển đến
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]59, tất cả các phương thức này sẽ trả về giá trị của đối tượng bị cắt bớt thành một [thường là một ]
Chức năng tích hợp sẽ quay trở lại nếu không được xác định hoặc không được xác định
Đã thay đổi trong phiên bản 3. 11. Việc ủy quyền của to không được dùng nữa.
3. 3. 9. Với Trình quản lý ngữ cảnh câu lệnh
Trình quản lý bối cảnh là một đối tượng xác định bối cảnh thời gian chạy sẽ được thiết lập khi thực thi một câu lệnh. Trình quản lý ngữ cảnh xử lý việc nhập và thoát khỏi ngữ cảnh thời gian chạy mong muốn để thực thi khối mã. Trình quản lý bối cảnh thường được gọi bằng cách sử dụng câu lệnh
class Philosopher: def __init_subclass__[cls, /, default_name, **kwargs]: super[].__init_subclass__[**kwargs] cls.default_name = default_name class AustralianPhilosopher[Philosopher, default_name="Bruce"]: pass8 [được mô tả trong phần ], nhưng cũng có thể được sử dụng bằng cách gọi trực tiếp các phương thức của chúng
Các ứng dụng điển hình của trình quản lý bối cảnh bao gồm lưu và khôi phục các loại trạng thái toàn cầu khác nhau, khóa và mở khóa tài nguyên, đóng các tệp đã mở, v.v.
Để biết thêm thông tin về trình quản lý ngữ cảnh, hãy xem
đối tượng. __enter__[bản thân]Nhập bối cảnh thời gian chạy liên quan đến đối tượng này. Câu lệnh sẽ liên kết giá trị trả về của phương thức này với [các] mục tiêu được chỉ định trong mệnh đề
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]71 của câu lệnh, nếu cóđối tượng. __exit__[self , exc_type, exc_value, traceback]
Thoát bối cảnh thời gian chạy liên quan đến đối tượng này. Các tham số mô tả ngoại lệ khiến ngữ cảnh bị thoát. Nếu ngữ cảnh được thoát mà không có ngoại lệ, thì cả ba đối số sẽ là
Nếu một ngoại lệ được cung cấp và phương thức muốn loại bỏ ngoại lệ đó [i. e. , ngăn nó lan truyền], nó sẽ trả về một giá trị thực. Mặt khác, ngoại lệ sẽ được xử lý bình thường khi thoát khỏi phương thức này
Note that methods should not reraise the passed-in exception; this is the caller’s responsibility
See also
PEP 343 - Câu lệnh “với”Thông số kỹ thuật, nền tảng và ví dụ cho câu lệnh Python
3. 3. 10. Tùy chỉnh đối số vị trí trong đối sánh mẫu lớp
Khi sử dụng tên lớp trong một mẫu, các đối số vị trí trong mẫu không được phép theo mặc định, tôi. e.
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]75 thường không hợp lệ nếu không có sự hỗ trợ đặc biệt trong
class Meta[type]: pass class MyClass[metaclass=Meta]: pass class MySubclass[MyClass]: pass98. Để có thể sử dụng loại mẫu đó, lớp cần xác định thuộc tính __match_args__đối tượng. __match_args__
Biến lớp này có thể được gán một bộ chuỗi. Khi lớp này được sử dụng trong mẫu lớp có đối số vị trí, mỗi đối số vị trí sẽ được chuyển đổi thành đối số từ khóa, sử dụng giá trị tương ứng trong __match_args__ làm từ khóa. Việc không có thuộc tính này tương đương với việc đặt nó thành
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]77
Ví dụ: nếu
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]78 là
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]79 có nghĩa là
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]75 tương đương với
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]81. Lưu ý rằng số đối số trong mẫu phải nhỏ hơn hoặc bằng số phần tử trong __match_args__;
Mới trong phiên bản 3. 10
See also
PEP 634 - Structural Pattern MatchingThông số kỹ thuật cho câu lệnh Python
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]83
3. 3. 11. Tra cứu phương pháp đặc biệt
Đối với các lớp tùy chỉnh, các lời gọi ẩn của các phương thức đặc biệt chỉ được đảm bảo hoạt động chính xác nếu được định nghĩa trên một loại đối tượng, không phải trong từ điển thể hiện của đối tượng. Hành vi đó là lý do tại sao đoạn mã sau đưa ra một ngoại lệ
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule1
Lý do đằng sau hành vi này nằm ở một số phương thức đặc biệt như và được thực hiện bởi tất cả các đối tượng, bao gồm các đối tượng kiểu. Nếu tra cứu ẩn của các phương thức này sử dụng quy trình tra cứu thông thường, chúng sẽ thất bại khi được gọi trên chính đối tượng loại
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule2
Việc cố gọi sai một phương thức không liên kết của một lớp theo cách này đôi khi được gọi là 'sự nhầm lẫn siêu lớp' và tránh được bằng cách bỏ qua thể hiện khi tra cứu các phương thức đặc biệt
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule3
Ngoài việc bỏ qua bất kỳ thuộc tính thể hiện nào vì lợi ích của tính chính xác, tra cứu phương thức đặc biệt ngầm thường cũng bỏ qua phương thức ngay cả trong siêu dữ liệu của đối tượng
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule4
Bỏ qua máy móc theo kiểu này cung cấp phạm vi đáng kể cho việc tối ưu hóa tốc độ trong trình thông dịch, với chi phí linh hoạt trong việc xử lý các phương thức đặc biệt [phương thức đặc biệt phải được đặt trên chính đối tượng lớp để được trình thông dịch gọi một cách nhất quán]
3. 4. Quy trình
3. 4. 1. Đối tượng có thể chờ đợi
Một đối tượng thường thực hiện một phương thức. được trả về từ các chức năng được chờ đợi
Ghi chú
Các đối tượng được trả về từ các trình tạo được trang trí cũng có thể chờ đợi, nhưng chúng không thực hiện
đối tượng. __await__[bản thân]Phải trả lại một. Nên được sử dụng để thực hiện các đối tượng. Chẳng hạn, triển khai phương thức này để tương thích với biểu thức
Ghi chú
Ngôn ngữ không đặt ra bất kỳ hạn chế nào đối với loại hoặc giá trị của các đối tượng do trình vòng lặp mang lại được trả về bởi
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]94, vì điều này dành riêng cho việc triển khai khung thực thi không đồng bộ [e. g. ] sẽ quản lý đối tượng
Mới trong phiên bản 3. 5
See also
PEP 492 để biết thêm thông tin về các đối tượng có thể chờ đợi
3. 4. 2. Đối tượng Coroutine
là đối tượng. Việc thực thi của một coroutine có thể được kiểm soát bằng cách gọi và lặp lại kết quả. Khi coroutine đã thực thi xong và trả về, trình vòng lặp tăng lên và thuộc tính
class A: pass c = C[] A.x = c # The hook is not called c.__set_name__[A, 'x'] # Manually invoke the hook94 của ngoại lệ giữ giá trị trả về. Nếu coroutine đưa ra một ngoại lệ, nó sẽ được nhân rộng bởi iterator. Coroutines không nên trực tiếp đưa ra các ngoại lệ chưa được xử lý
Coroutine cũng có các phương thức được liệt kê bên dưới, tương tự như các phương thức của bộ tạo [xem phần ]. Tuy nhiên, không giống như các trình tạo, các coroutine không hỗ trợ trực tiếp phép lặp
Đã thay đổi trong phiên bản 3. 5. 2. Việc chờ đợi trên một coroutine nhiều hơn một lần.
quy trình. gửi[giá trị]Bắt đầu hoặc tiếp tục thực thi coroutine. Nếu giá trị là
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8, điều này tương đương với việc nâng cấp trình vòng lặp được trả về bởi. Nếu giá trị không phải là
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8, thì phương thức này ủy quyền cho phương thức của trình vòng lặp khiến quy trình đăng ký tạm dừng. Kết quả [giá trị trả về, hoặc ngoại lệ khác] giống như khi lặp lại giá trị trả về
>>> from enum import Enum >>> class Menu[Enum]: .. """A breakfast menu""" .. SPAM = 'spam' .. BACON = 'bacon' ... >>> # Enum classes have a custom metaclass: >>> type[Menu] >>> # EnumMeta defines __getitem__, >>> # so __class_getitem__ is not called, >>> # and the result is not a GenericAlias object: >>> Menu['SPAM'] >>> type[Menu['SPAM']]88, được mô tả ở trênquy trình. ném[giá trị]coroutine. ném[loại[ , value[, traceback]]]
Tăng ngoại lệ được chỉ định trong coroutine. Phương thức này ủy quyền cho phương thức của iterator khiến coroutine tạm dừng, nếu nó có một phương thức như vậy. Mặt khác, ngoại lệ được nâng lên tại điểm treo. Kết quả [giá trị trả về, hoặc ngoại lệ khác] giống như khi lặp lại giá trị trả về, được mô tả ở trên. Nếu ngoại lệ không bị bắt trong coroutine, nó sẽ truyền lại cho người gọi
quy trình. đóng[]Khiến coroutine tự dọn dẹp và thoát. Nếu coroutine bị đình chỉ, phương thức này trước tiên sẽ ủy quyền cho phương thức của iterator đã khiến coroutine bị đình chỉ, nếu nó có một phương thức như vậy. Sau đó, nó nâng lên tại điểm treo, khiến coroutine ngay lập tức tự dọn dẹp. Cuối cùng, coroutine được đánh dấu là đã thực thi xong, ngay cả khi nó chưa bao giờ được bắt đầu
Các đối tượng Coroutine được tự động đóng bằng quy trình trên khi chúng sắp bị hủy
3. 4. 3. Trình lặp không đồng bộ
Trình lặp không đồng bộ có thể gọi mã không đồng bộ theo phương thức
a[1:2] = b12 của nó
Trình lặp không đồng bộ có thể được sử dụng trong một câu lệnh
đối tượng. __aiter__[bản thân]Phải trả về một đối tượng lặp không đồng bộ
đối tượng. __anext__[bản thân]Phải trả về một kết quả có thể chờ đợi trong giá trị tiếp theo của trình vòng lặp. Sẽ phát sinh lỗi khi quá trình lặp kết thúc
Một ví dụ về một đối tượng có thể lặp lại không đồng bộ
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule5
Mới trong phiên bản 3. 5
Đã thay đổi trong phiên bản 3. 7. Trước Python 3. 7, có thể trả về một sự chờ đợi sẽ phân giải thành một.
Bắt đầu với Python 3. 7, phải trả về một đối tượng lặp không đồng bộ. Trả lại bất cứ thứ gì khác sẽ dẫn đến lỗi
3. 4. 4. Asynchronous Context Managers
Trình quản lý ngữ cảnh không đồng bộ là trình quản lý ngữ cảnh có khả năng tạm dừng thực thi trong các phương thức
a[1:2] = b18 và
a[1:2] = b19 của nó
Trình quản lý bối cảnh không đồng bộ có thể được sử dụng trong một câu lệnh
đối tượng. __aenter__[bản thân]Semantically similar to , the only difference being that it must return an awaitable
đối tượng. __aexit__[bản thân , exc_type, exc_value, traceback]Semantically similar to , the only difference being that it must return an awaitable
Một ví dụ về lớp trình quản lý ngữ cảnh không đồng bộ
import sys from types import ModuleType class VerboseModule[ModuleType]: def __repr__[self]: return f'Verbose {self.__name__}' def __setattr__[self, attr, value]: print[f'Setting {attr}...'] super[].__setattr__[attr, value] sys.modules[__name__].__class__ = VerboseModule6
Mới trong phiên bản 3. 5
chú thích
Trong một số trường hợp, có thể thay đổi loại đối tượng, trong các điều kiện được kiểm soát nhất định. Mặc dù vậy, nhìn chung đó không phải là một ý kiến hay, vì nó có thể dẫn đến một số hành vi rất kỳ lạ nếu xử lý không đúng cách.
Các phương thức , , và có cách xử lý đặc biệt cho việc này;
“Không hỗ trợ” ở đây có nghĩa là lớp không có phương thức như vậy hoặc phương thức trả về
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']9. Không đặt phương thức thành
class A: x = C[] # Automatically calls: x.__set_name__[A, 'x']8 nếu bạn muốn buộc dự phòng về phương thức phản ánh của toán hạng bên phải—thay vào đó, điều đó sẽ có tác dụng ngược lại là chặn dự phòng đó một cách rõ ràng
Đối với các toán hạng cùng loại, người ta cho rằng nếu phương thức không được phản ánh - chẳng hạn như - không thành công thì hoạt động tổng thể không được hỗ trợ, đó là lý do tại sao phương thức được phản ánh không được gọi