Python menimpa __getattr__ dan __setattr__

Objek adalah abstraksi Python untuk data. Semua data dalam program Python diwakili oleh objek atau hubungan antar objek. (Dalam arti tertentu, dan sesuai dengan model "komputer program tersimpan" Von Neumann, kode juga diwakili oleh objek. )

Setiap objek memiliki identitas, tipe dan nilai. Identitas objek tidak pernah berubah setelah dibuat; . Operator ‘’ membandingkan identitas dua objek;

Detail implementasi CPython. Untuk 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__ = VerboseModule
_9 adalah alamat memori tempat
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
0 disimpan

Jenis objek menentukan operasi yang didukung objek (mis. g. , "apakah itu memiliki panjang?") dan juga menentukan nilai yang mungkin untuk objek jenis itu. Fungsi mengembalikan tipe objek (yang merupakan objek itu sendiri). Seperti identitasnya, tipe objek juga tidak dapat diubah.

Nilai beberapa objek dapat berubah. Objek yang nilainya dapat berubah dikatakan bisa berubah; . (Nilai objek wadah yang tidak dapat diubah yang berisi referensi ke objek yang dapat diubah dapat berubah ketika nilai yang terakhir diubah; namun wadah tersebut masih dianggap tidak dapat diubah, karena koleksi objek yang dikandungnya tidak dapat diubah. Jadi, kekekalan tidak sepenuhnya sama dengan memiliki nilai yang tidak dapat diubah, ini lebih halus. ) Mutabilitas suatu objek ditentukan oleh jenisnya;

Objek tidak pernah dihancurkan secara eksplisit; . Implementasi diperbolehkan untuk menunda pengumpulan sampah atau menghilangkannya sama sekali — ini masalah kualitas implementasi bagaimana pengumpulan sampah diterapkan, selama tidak ada objek yang dikumpulkan yang masih dapat dijangkau

Detail implementasi CPython. CPython saat ini menggunakan skema penghitungan referensi dengan (opsional) deteksi tertunda dari sampah yang terhubung secara siklis, yang mengumpulkan sebagian besar objek segera setelah tidak dapat dijangkau, tetapi tidak dijamin untuk mengumpulkan sampah yang berisi referensi melingkar. Lihat dokumentasi modul untuk informasi tentang pengendalian pengumpulan sampah siklik. Implementasi lain bertindak berbeda dan CPython dapat berubah. 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. Perhatikan juga bahwa menangkap pengecualian dengan pernyataan '…' dapat membuat objek tetap hidup

Beberapa objek berisi referensi ke sumber daya "eksternal" seperti file atau jendela yang terbuka. 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"):
    pass
5 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. Examples of containers are tuples, lists and dictionaries. The references are part of a container’s value. In most cases, when we talk about the value of a container, we imply the values, not the identities of the contained objects; however, when we talk about the mutability of a container, only the identities of the immediately contained objects are implied. So, if an immutable container (like a tuple) contains a reference to a mutable object, its value changes if that mutable object is changed

Types affect almost all aspects of object behavior. Bahkan pentingnya identitas objek dipengaruhi dalam arti tertentu. for immutable types, operations that compute new values may actually return a reference to any existing object with the same type and value, while for mutable objects this is not allowed. E. g. , after

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
9,
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
0 and
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
1 may or may not refer to the same object with the value one, depending on the implementation, but after
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
2,
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
3 and
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
4 are guaranteed to refer to two different, unique, newly created empty lists. (Note that
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
5 assigns the same object to both
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
3 and
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
4. )

3. 2. The standard type hierarchy

Below is a list of the types that are built into Python. Extension modules (written in C, Java, or other languages, depending on the implementation) can define additional types. Future versions of Python may add types to the type hierarchy (e. g. , rational numbers, efficiently stored arrays of integers, etc. ), although such additions will often be provided via the standard library instead

Some of the type descriptions below contain a paragraph listing ‘special attributes. ’ These are attributes that provide access to the implementation and are not intended for general use. Their definition may change in the future

None

This type has a single value. There is a single object with this value. This object is accessed through the built-in name

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8. It is used to signify the absence of a value in many situations, e. g. , it is returned from functions that don’t explicitly return anything. Its truth value is false

NotImplemented

This type has a single value. There is a single object with this value. This object is accessed through the built-in name

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 hook
3 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 hook
4. 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

Bilangan bulat ()

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):
    pass
1 and
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
2 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):
    pass
3 or
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
4 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):
    pass
9 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"
        )
1

Sequences

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)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
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 sequences

An 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

String

String adalah urutan nilai yang mewakili poin kode Unicode. Semua titik kode dalam rentang

>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
3 dapat direpresentasikan dalam sebuah string. Python tidak memiliki tipe char ; . Fungsi bawaan mengonversi titik kode dari bentuk stringnya menjadi bilangan bulat dalam rentang
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
6; . dapat digunakan untuk mengonversi a menjadi menggunakan pengkodean teks yang diberikan, dan dapat digunakan untuk mencapai kebalikannya.

Tupel

Item tuple adalah objek Python yang sewenang-wenang. Tupel dari dua item atau lebih dibentuk oleh daftar ekspresi yang dipisahkan koma. Tuple dari satu item (sebuah 'singleton') dapat dibentuk dengan membubuhkan tanda koma pada sebuah ekspresi (sebuah ekspresi dengan sendirinya tidak membuat sebuah tupel, karena tanda kurung harus dapat digunakan untuk pengelompokan ekspresi). Tuple kosong dapat dibentuk oleh sepasang tanda kurung kosong

Byte

Objek bytes adalah array yang tidak dapat diubah. Itemnya adalah byte 8-bit, diwakili oleh bilangan bulat dalam rentang 0 <= x < 256. Literal byte (seperti

>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
4) dan konstruktor bawaan dapat digunakan untuk membuat objek byte. Selain itu, objek byte dapat didekodekan menjadi string melalui metode ini

Urutan yang bisa berubah

Urutan yang dapat diubah dapat diubah setelah dibuat. Notasi langganan dan pemotongan dapat digunakan sebagai target penugasan dan pernyataan (hapus).

Saat ini ada dua jenis urutan intrinsik yang bisa berubah

Daftar

Item dari daftar adalah objek Python yang sewenang-wenang. Daftar dibentuk dengan menempatkan daftar ekspresi yang dipisahkan koma dalam tanda kurung siku. (Perhatikan bahwa tidak ada kasus khusus yang diperlukan untuk membentuk daftar dengan panjang 0 atau 1. )

Byte Array

Objek bytearray adalah array yang bisa berubah. Mereka dibuat oleh konstruktor bawaan. Selain bisa berubah (dan karenanya tidak bisa dihash), array byte juga menyediakan antarmuka dan fungsionalitas yang sama dengan objek yang tidak dapat diubah

Modul ekstensi memberikan contoh tambahan dari jenis urutan yang dapat diubah, seperti halnya modul

Tetapkan jenis

Ini mewakili kumpulan objek unik dan tidak berubah yang tidak terurut dan terbatas. Dengan demikian, mereka tidak dapat diindeks oleh subskrip apa pun. Namun, mereka dapat diulang, dan fungsi bawaan mengembalikan jumlah item dalam satu set. Kegunaan umum untuk set adalah pengujian keanggotaan cepat, menghapus duplikat dari urutan, dan menghitung operasi matematika seperti persimpangan, penyatuan, perbedaan, dan perbedaan simetris

Untuk elemen set, aturan kekekalan yang sama berlaku untuk kunci kamus. Perhatikan bahwa tipe numerik mematuhi aturan normal untuk perbandingan numerik. jika dua angka membandingkan sama (mis. g. ,

>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
4 dan
a[1:2] = b
4), hanya salah satunya yang dapat dimuat dalam satu set

Saat ini ada dua jenis himpunan intrinsik

Set

Ini mewakili set yang bisa berubah. Mereka dibuat oleh konstruktor bawaan dan dapat dimodifikasi setelahnya dengan beberapa metode, seperti

a[1:2] = b
6

Set beku

Ini mewakili satu set yang tidak dapat diubah. Mereka dibuat oleh konstruktor bawaan. Karena frozenset tidak dapat diubah dan , dapat digunakan lagi sebagai elemen dari set lain, atau sebagai kunci kamus

Pemetaan

Ini mewakili set objek terbatas yang diindeks oleh set indeks sewenang-wenang. Notasi subskrip

a[1:2] = b
8 memilih item yang diindeks oleh
a[1:2] = b
9 dari pemetaan
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
0; . Fungsi bawaan mengembalikan jumlah item dalam pemetaan

Saat ini ada satu jenis pemetaan intrinsik

Kamus

Ini mewakili kumpulan objek terbatas yang diindeks oleh nilai yang hampir sewenang-wenang. Satu-satunya jenis nilai yang tidak dapat diterima sebagai kunci adalah nilai yang berisi daftar atau kamus atau jenis lain yang dapat diubah yang dibandingkan dengan nilai daripada identitas objek, alasannya karena penerapan kamus yang efisien memerlukan nilai hash kunci untuk tetap konstan. Jenis numerik yang digunakan untuk kunci mematuhi aturan normal untuk perbandingan numerik. jika dua angka membandingkan sama (mis. g. ,

>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
4 dan
a[1:2] = b
4) maka mereka dapat digunakan secara bergantian untuk mengindeks entri kamus yang sama

Kamus mempertahankan urutan penyisipan, yang berarti bahwa kunci akan diproduksi dalam urutan yang sama dengan yang ditambahkan secara berurutan di atas kamus. Mengganti kunci yang ada tidak mengubah urutan, namun menghapus kunci dan memasukkannya kembali akan menambahkannya ke akhir alih-alih mempertahankan tempat lamanya

Kamus bisa berubah;

Modul ekstensi dan memberikan contoh tambahan tentang jenis pemetaan, seperti halnya modul

Berubah di versi 3. 7. Kamus tidak mempertahankan urutan penyisipan dalam versi Python sebelum 3. 6. Di CPython 3. 6, urutan penyisipan dipertahankan, tetapi pada saat itu dianggap sebagai detail implementasi daripada jaminan bahasa.

Jenis yang dapat dipanggil

Ini adalah jenis operasi pemanggilan fungsi (lihat bagian ) yang dapat diterapkan

Fungsi yang ditentukan pengguna

Objek fungsi yang ditentukan pengguna dibuat oleh definisi fungsi (lihat bagian ). Itu harus dipanggil dengan daftar argumen yang berisi jumlah item yang sama dengan daftar parameter formal fungsi

Atribut khusus

Atribut

Arti

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
_09

String dokumentasi fungsi, atau

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8 jika tidak tersedia;

Dapat ditulis

Nama fungsi

Dapat ditulis

Fungsinya

Baru di versi 3. 3

Dapat ditulis

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
_13

Nama modul tempat fungsi didefinisikan, atau

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8 jika tidak tersedia

Dapat ditulis

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
_15

Tuple berisi nilai argumen default untuk argumen yang memiliki nilai default, atau

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8 jika tidak ada argumen yang memiliki nilai default

Dapat ditulis

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
_17

Objek kode yang mewakili badan fungsi yang dikompilasi

Dapat ditulis

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
_18

Referensi ke kamus yang menyimpan variabel global fungsi — ruang nama global modul tempat fungsi didefinisikan

Hanya baca

Namespace yang mendukung atribut fungsi arbitrer

Dapat ditulis

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
_20

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
_8 atau tupel sel yang berisi binding untuk variabel bebas fungsi. Lihat di bawah untuk informasi tentang
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
_22 atribut

Hanya baca

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
_23

Dikt yang berisi anotasi parameter. Kunci dict adalah nama parameter, dan

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
24 untuk anotasi pengembalian, jika tersedia. Untuk informasi selengkapnya tentang bekerja dengan atribut ini, lihat

Dapat ditulis

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
_25

Dict berisi default untuk parameter kata kunci saja

Dapat ditulis

Sebagian besar atribut berlabel "Writable" memeriksa jenis nilai yang ditetapkan

Objek fungsi juga mendukung pengambilan dan pengaturan atribut arbitrer, yang dapat digunakan, misalnya, untuk melampirkan metadata ke fungsi. Atribut dot-notasi reguler digunakan untuk mendapatkan dan mengatur atribut tersebut. Perhatikan bahwa implementasi saat ini hanya mendukung atribut fungsi pada fungsi yang ditentukan pengguna. Atribut fungsi pada fungsi bawaan mungkin didukung di masa mendatang

Objek sel memiliki atribut

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
_22. Ini dapat digunakan untuk mendapatkan nilai sel, serta mengatur nilainya

Informasi tambahan tentang definisi fungsi dapat diambil dari objek kodenya; . Jenis dapat diakses dalam modul

Metode instan

Objek metode instance menggabungkan kelas, instance kelas, dan objek apa pun yang dapat dipanggil (biasanya fungsi yang ditentukan pengguna)

Atribut hanya-baca khusus.

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
29 adalah objek contoh kelas,
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
30 adalah objek fungsi;

Metode juga mendukung pengaksesan (tetapi tidak menyetel) atribut fungsi arbitrer pada objek fungsi yang mendasarinya

Objek metode yang ditentukan pengguna dapat dibuat saat mendapatkan atribut kelas (mungkin melalui turunan dari kelas itu), jika atribut itu adalah objek fungsi yang ditentukan pengguna atau objek metode kelas

Ketika objek metode instance dibuat dengan mengambil objek fungsi yang ditentukan pengguna dari kelas melalui salah satu instance-nya, atribut

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
29 adalah instance, dan objek metode dikatakan terikat. Atribut
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
_30 metode baru adalah objek fungsi asli

Ketika objek metode instance dibuat dengan mengambil objek metode kelas dari kelas atau instance, atribut

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
29 adalah kelas itu sendiri, dan atribut
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
30 adalah objek fungsi yang mendasari metode kelas

Ketika objek metode instance dipanggil, fungsi yang mendasari (

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
30) dipanggil, menyisipkan instance kelas (
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
29) di depan daftar argumen. Misalnya, ketika
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
43 adalah kelas yang berisi definisi untuk fungsi
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
44, dan
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
0 adalah turunan dari
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
43, memanggil
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
47 sama dengan memanggil
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
48

Ketika objek metode instance diturunkan dari objek metode kelas, "instance kelas" yang disimpan di

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
29 sebenarnya akan menjadi kelas itu sendiri, sehingga memanggil
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
47 atau
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
51 sama dengan memanggil
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
52 di mana
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
53 adalah fungsi yang mendasarinya

Perhatikan bahwa transformasi dari objek fungsi ke objek metode instance terjadi setiap kali atribut diambil dari instance. Dalam beberapa kasus, pengoptimalan yang berhasil adalah menetapkan atribut ke variabel lokal dan memanggil variabel lokal tersebut. Perhatikan juga bahwa transformasi ini hanya terjadi untuk fungsi yang ditentukan pengguna; . Penting juga untuk dicatat bahwa fungsi yang ditentukan pengguna yang merupakan atribut dari instance kelas tidak diubah menjadi metode terikat;

Fungsi pembangkit

Sebuah fungsi atau metode yang menggunakan pernyataan (lihat bagian ) disebut fungsi generator. Fungsi seperti itu, ketika dipanggil, selalu mengembalikan objek yang dapat digunakan untuk mengeksekusi badan fungsi. memanggil metode iterator akan menyebabkan fungsi dieksekusi hingga memberikan nilai menggunakan pernyataan

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
54. Ketika fungsi mengeksekusi pernyataan atau jatuh dari akhir, pengecualian dimunculkan dan iterator akan mencapai akhir dari kumpulan nilai yang akan dikembalikan

Fungsi coroutine

Fungsi atau metode yang didefinisikan menggunakan disebut fungsi coroutine. Fungsi seperti itu, saat dipanggil, mengembalikan objek. Ini mungkin berisi ekspresi, serta dan pernyataan. Lihat juga bagian

Fungsi generator asinkron

Fungsi atau metode yang didefinisikan menggunakan dan yang menggunakan pernyataan disebut fungsi generator asinkron. Fungsi seperti itu, ketika dipanggil, mengembalikan objek yang dapat digunakan dalam pernyataan untuk mengeksekusi badan fungsi

Memanggil metode iterator asinkron akan mengembalikan which ketika ditunggu akan dieksekusi hingga memberikan nilai menggunakan ekspresi. Ketika fungsi mengeksekusi pernyataan kosong atau jatuh dari akhir, pengecualian dimunculkan dan iterator asinkron akan mencapai akhir dari kumpulan nilai yang akan dihasilkan

Fungsi bawaan

Objek fungsi bawaan adalah pembungkus di sekitar fungsi C. Contoh fungsi bawaan adalah dan ( adalah modul bawaan standar). Jumlah dan jenis argumen ditentukan oleh fungsi C. Atribut hanya-baca khusus.

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
_09 adalah string dokumentasi fungsi, atau
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8 jika tidak tersedia;

Metode bawaan

Ini benar-benar penyamaran yang berbeda dari fungsi bawaan, kali ini berisi objek yang diteruskan ke fungsi C sebagai argumen tambahan implisit. Contoh metode bawaan adalah

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
80, dengan asumsi alist adalah objek daftar. Dalam hal ini, atribut read-only khusus
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
29 disetel ke objek yang dilambangkan dengan alist

Kelas

Kelas dapat dipanggil. Objek-objek ini biasanya bertindak sebagai pabrik untuk instance baru dari dirinya sendiri, tetapi variasi dimungkinkan untuk tipe kelas yang menimpa. Argumen panggilan diteruskan ke

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
82 dan, dalam kasus tipikal, ke untuk menginisialisasi instance baru

Contoh Kelas

Instance kelas arbitrer dapat dibuat dapat dipanggil dengan mendefinisikan metode di kelasnya

Modul

Modul adalah unit organisasi dasar dari kode Python, dan dibuat oleh as yang dipanggil baik oleh pernyataan, atau dengan memanggil fungsi seperti dan built-in. Objek modul memiliki ruang nama yang diimplementasikan oleh objek kamus (ini adalah kamus yang direferensikan oleh

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
18 atribut fungsi yang didefinisikan dalam modul). Referensi atribut diterjemahkan ke pencarian dalam kamus ini, mis. 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__ = VerboseModule
_90 setara dengan
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
91. Objek modul tidak berisi objek kode yang digunakan untuk menginisialisasi modul (karena tidak diperlukan setelah inisialisasi selesai)

Penugasan atribut memperbarui kamus namespace modul, mis. 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__ = VerboseModule
_92 setara dengan
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
93

Atribut yang telah ditentukan sebelumnya (dapat ditulis).

Nama modul

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
_09

String dokumentasi modul, atau

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8 jika tidak tersedia

Nama jalur file tempat modul dimuat, jika diambil dari file. Atribut mungkin hilang untuk jenis modul tertentu, seperti modul C yang terhubung secara statis ke juru bahasa. Untuk modul ekstensi yang dimuat secara dinamis dari pustaka bersama, ini adalah nama jalur dari file pustaka bersama

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
_23

Kamus berisi yang dikumpulkan selama eksekusi badan modul. Untuk praktik terbaik dalam bekerja dengan

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
_23, silakan lihat

Atribut hanya-baca khusus. adalah ruang nama modul sebagai objek kamus

Detail implementasi CPython. Karena cara CPython menghapus kamus modul, kamus modul akan dihapus ketika modul keluar dari ruang lingkup bahkan jika kamus masih memiliki referensi langsung. Untuk menghindarinya, salin kamus atau simpan modul saat menggunakan kamusnya secara langsung

Kelas khusus

Jenis kelas khusus biasanya dibuat berdasarkan definisi kelas (lihat bagian ). Kelas memiliki namespace yang diimplementasikan oleh objek kamus. Referensi atribut kelas diterjemahkan ke pencarian dalam kamus ini, mis. 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"):
    pass
_02 diterjemahkan menjadi
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
03 (meskipun ada sejumlah kait yang memungkinkan cara lain untuk menemukan atribut). Ketika nama atribut tidak ditemukan di sana, pencarian atribut dilanjutkan di kelas dasar. Pencarian kelas dasar ini menggunakan urutan resolusi metode C3 yang berperilaku benar bahkan di hadapan struktur pewarisan 'berlian' di mana ada banyak jalur pewarisan yang mengarah kembali ke nenek moyang yang sama. Detail tambahan tentang MRO C3 yang digunakan oleh Python dapat ditemukan dalam dokumentasi yang menyertai 2. 3 rilis di https. // www. python. org/unduh/rilis/2. 3/mro/

Ketika referensi atribut kelas (untuk kelas

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
43, katakanlah) akan menghasilkan objek metode kelas, itu diubah menjadi objek metode instance yang atribut
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
29 adalah
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
43. Ketika itu akan menghasilkan objek metode statis, itu diubah menjadi objek yang dibungkus oleh objek metode statis. Lihat bagian untuk cara lain di mana atribut yang diambil dari kelas mungkin berbeda dari yang sebenarnya terkandung di dalamnya

Penugasan atribut kelas memperbarui kamus kelas, bukan kamus kelas dasar

Objek kelas dapat dipanggil (lihat di atas) untuk menghasilkan instance kelas (lihat di bawah)

Atribut khusus

Nama kelas

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
_13

Nama modul tempat kelas didefinisikan

Kamus yang berisi ruang nama kelas

Tuple yang berisi kelas dasar, sesuai urutan kemunculannya dalam daftar kelas dasar

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
_09

String dokumentasi kelas, atau

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8 jika tidak ditentukan

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
_23

Kamus yang berisi dikumpulkan selama eksekusi badan kelas. Untuk praktik terbaik dalam bekerja dengan

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
_23, silakan lihat

Instance kelas

Instance kelas dibuat dengan memanggil objek kelas (lihat di atas). Instance kelas memiliki namespace yang diimplementasikan sebagai kamus yang merupakan tempat pertama di mana referensi atribut dicari. Ketika atribut tidak ditemukan di sana, dan kelas instance memiliki atribut dengan nama itu, pencarian dilanjutkan dengan atribut kelas. Jika atribut kelas ditemukan yang merupakan objek fungsi yang ditentukan pengguna, itu diubah menjadi objek metode instance yang

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
29 atributnya adalah instance. Objek metode statis dan metode kelas juga diubah; . Lihat bagian untuk cara lain di mana atribut kelas yang diambil melalui instansnya mungkin berbeda dari objek yang sebenarnya disimpan di kelas. Jika tidak ada atribut kelas yang ditemukan, dan kelas objek memiliki metode, yang dipanggil untuk memenuhi pencarian

Penugasan dan penghapusan atribut memperbarui kamus instance, bukan kamus kelas. Jika kelas memiliki atau metode, ini dipanggil alih-alih memperbarui kamus instance secara langsung

Instance kelas dapat berpura-pura menjadi angka, urutan, atau pemetaan jika mereka memiliki metode dengan nama khusus tertentu. Lihat bagian

Atribut khusus. adalah kamus atribut;

Objek I/O (juga dikenal sebagai objek file)

A mewakili file terbuka. Berbagai pintasan tersedia untuk membuat objek file. fungsi bawaan, dan juga , , dan metode objek soket (dan mungkin dengan fungsi atau metode lain yang disediakan oleh modul ekstensi)

Objek

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
_27,
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
28 dan
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
29 diinisialisasi ke objek file yang sesuai dengan aliran input, output, dan kesalahan standar penafsir;

Tipe dalam

Beberapa jenis yang digunakan secara internal oleh juru bahasa diekspos ke pengguna. Definisi mereka dapat berubah dengan versi penerjemah yang akan datang, tetapi mereka disebutkan di sini untuk kelengkapan

Objek kode

Objek kode mewakili kode Python yang dapat dieksekusi yang dikompilasi byte, atau. Perbedaan antara objek kode dan objek fungsi adalah bahwa objek fungsi berisi referensi eksplisit ke global fungsi (modul yang mendefinisikannya), sedangkan objek kode tidak berisi konteks; . Tidak seperti objek fungsi, objek kode tidak dapat diubah dan tidak mengandung referensi (langsung atau tidak langsung) ke objek yang dapat diubah

Atribut hanya-baca khusus.

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
_31 memberikan nama fungsi;

Bit flag berikut didefinisikan untuk

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
47. 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"):
    pass
_49 disetel jika fungsi menggunakan sintaks
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
50 untuk menerima sejumlah argumen posisi;

Deklarasi fitur mendatang (

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
54) juga menggunakan bit di
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
47 untuk menunjukkan apakah objek kode dikompilasi dengan fitur tertentu diaktifkan. 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"):
    pass
_56 disetel jika fungsi dikompilasi dengan pembagian masa depan diaktifkan;

Bit lain di

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
_47 dicadangkan untuk penggunaan internal

Jika objek kode mewakili suatu fungsi, item pertama di

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
41 adalah string dokumentasi dari fungsi tersebut, atau
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8 jika tidak ditentukan

kodeobjek. co_positions()

Mengembalikan iterable atas posisi kode sumber dari setiap instruksi bytecode dalam objek kode

Iterator mengembalikan tupel yang berisi

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
62. Tuple ke-i sesuai dengan posisi kode sumber yang dikompilasi ke instruksi ke-i. Informasi kolom adalah 0-diindeks utf-8 byte offset pada baris sumber yang diberikan

Informasi posisi ini dapat hilang. Daftar kasus yang tidak lengkap di mana hal ini dapat terjadi

  • Menjalankan juru bahasa dengan

    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

  • Memuat file pyc yang dikompilasi saat menggunakan

    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

  • Posisikan tuple yang sesuai dengan instruksi buatan

  • Nomor baris dan kolom yang tidak dapat ditampilkan karena batasan khusus implementasi

Saat ini terjadi, beberapa atau semua elemen tuple bisa

Baru di versi 3. 11

Catatan

Fitur ini memerlukan penyimpanan posisi kolom dalam objek kode yang dapat mengakibatkan sedikit peningkatan penggunaan disk dari file Python yang dikompilasi atau penggunaan memori juru bahasa. Untuk menghindari menyimpan informasi ekstra dan/atau menonaktifkan pencetakan informasi traceback ekstra, flag baris perintah

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 atau variabel lingkungan dapat digunakan

Bingkai objek

Objek bingkai mewakili bingkai eksekusi. Mereka mungkin muncul di objek traceback (lihat di bawah), dan juga diteruskan ke fungsi trace terdaftar

Atribut hanya-baca khusus.

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
_71 adalah ke bingkai tumpukan sebelumnya (menuju pemanggil), atau
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8 jika ini adalah bingkai tumpukan bawah;

Mengakses

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
_73 memunculkan
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
79 dengan argumen
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
80 dan
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
81

Atribut khusus yang dapat ditulis.

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
_82, jika bukan
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8, adalah fungsi yang dipanggil untuk berbagai peristiwa selama eksekusi kode (ini digunakan oleh debugger). Biasanya suatu peristiwa dipicu untuk setiap baris sumber baru - ini dapat dinonaktifkan dengan menyetel
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
84 ke

Implementasi memungkinkan acara per-opcode diminta dengan menyetel

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
86 ke. Perhatikan bahwa ini dapat menyebabkan perilaku juru bahasa yang tidak terdefinisi jika pengecualian yang diajukan oleh fungsi pelacakan lolos ke fungsi yang sedang dilacak

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
_88 adalah nomor baris frame saat ini — menulisnya dari dalam fungsi jejak akan melompat ke baris yang diberikan (hanya untuk frame paling bawah). Seorang debugger dapat mengimplementasikan perintah Jump (alias Set Next Statement) dengan menulis ke f_lineno

Objek bingkai mendukung satu metode

bingkai. bersih()

Metode ini menghapus semua referensi ke variabel lokal yang dipegang oleh frame. Juga, jika bingkai milik generator, generator diselesaikan. Ini membantu memutus siklus referensi yang melibatkan objek bingkai (misalnya saat menangkap pengecualian dan menyimpan tracebacknya untuk digunakan nanti)

dinaikkan jika frame sedang dieksekusi

Baru di versi 3. 4

Objek jejak balik

Objek traceback mewakili jejak tumpukan pengecualian. Objek traceback dibuat secara implisit saat pengecualian terjadi, dan mungkin juga dibuat secara eksplisit dengan memanggil

Untuk traceback yang dibuat secara implisit, saat pencarian penangan pengecualian melepaskan tumpukan eksekusi, pada setiap level yang dibatalkan, objek traceback disisipkan di depan traceback saat ini. Saat penangan pengecualian dimasukkan, pelacakan tumpukan tersedia untuk program. (Lihat bagian. ) Ini dapat diakses sebagai item ketiga dari tuple yang dikembalikan oleh

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
91, dan sebagai atribut
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
92 dari pengecualian yang tertangkap

Ketika program tidak berisi penangan yang sesuai, pelacakan tumpukan ditulis (diformat dengan baik) ke aliran kesalahan standar;

Untuk traceback yang dibuat secara eksplisit, terserah pembuat traceback untuk menentukan bagaimana atribut

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
94 harus ditautkan untuk membentuk pelacakan tumpukan penuh

Atribut hanya-baca khusus.

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
_95 menunjuk ke kerangka eksekusi dari level saat ini; . Nomor baris dan instruksi terakhir dalam traceback mungkin berbeda dari nomor baris objek bingkainya jika pengecualian terjadi dalam pernyataan tanpa klausa kecuali yang cocok atau dengan klausa akhirnya

Mengakses

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
_95 memunculkan
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
79 dengan argumen
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
80 dan
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
02

Atribut khusus yang dapat ditulis.

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
_94 adalah level berikutnya dalam pelacakan tumpukan (menuju bingkai tempat pengecualian terjadi), atau
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8 jika tidak ada level berikutnya

Berubah di versi 3. 7. Objek traceback kini dapat dibuat instance-nya secara eksplisit dari kode Python, dan atribut

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
94 dari instance yang ada dapat diperbarui.

Iris objek

Objek irisan digunakan untuk merepresentasikan irisan untuk metode. Mereka juga dibuat oleh fungsi bawaan

Atribut hanya-baca khusus.

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
_08 adalah batas bawah; . Atribut ini dapat memiliki tipe apa pun

Objek irisan mendukung satu metode

iris. indeks(diri , panjang)

Metode ini mengambil panjang argumen integer tunggal dan menghitung informasi tentang irisan yang akan dideskripsikan oleh objek irisan jika diterapkan pada urutan item panjang. Ini mengembalikan Tuple dari tiga bilangan bulat; . Indeks yang hilang atau di luar batas ditangani dengan cara yang konsisten dengan irisan biasa

Objek metode statis

Objek metode statis menyediakan cara mengalahkan transformasi objek fungsi menjadi objek metode yang dijelaskan di atas. Objek metode statis adalah pembungkus di sekitar objek lain, biasanya objek metode yang ditentukan pengguna. Ketika objek metode statis diambil dari kelas atau instance kelas, objek yang sebenarnya dikembalikan adalah objek yang dibungkus, yang tidak tunduk pada transformasi lebih lanjut. Objek metode statis juga bisa dipanggil. Objek metode statis dibuat oleh konstruktor bawaan

Objek metode kelas

Objek metode kelas, seperti objek metode statis, adalah pembungkus di sekitar objek lain yang mengubah cara objek diambil dari kelas dan instance kelas. Perilaku objek metode kelas pada pengambilan tersebut dijelaskan di atas, di bawah "Metode yang ditentukan pengguna". Objek metode kelas dibuat oleh konstruktor bawaan

3. 3. Nama metode khusus

Kelas dapat mengimplementasikan operasi tertentu yang dipanggil oleh sintaks khusus (seperti operasi aritmatika atau subscripting dan slicing) dengan mendefinisikan metode dengan nama khusus. Ini adalah pendekatan Python untuk kelebihan operator, memungkinkan kelas untuk menentukan perilaku mereka sendiri sehubungan dengan operator bahasa. Misalnya, jika sebuah kelas mendefinisikan metode bernama , dan

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
0 adalah turunan dari kelas ini, maka
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
16 kira-kira setara dengan
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
17. Kecuali jika disebutkan, upaya untuk menjalankan operasi menimbulkan pengecualian ketika tidak ada metode yang tepat yang ditentukan (biasanya atau )

Menetapkan metode khusus ke

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
_8 menunjukkan bahwa operasi terkait tidak tersedia. Misalnya, jika sebuah kelas disetel ke
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
_8, kelas tersebut tidak dapat diubah, jadi memanggil instance-nya akan menaikkan a (tanpa kembali ke ).

Saat mengimplementasikan kelas yang mengemulasi tipe bawaan apa pun, penting agar emulasi hanya diimplementasikan pada tingkat yang masuk akal untuk objek yang dimodelkan. Misalnya, beberapa sekuens mungkin bekerja dengan baik dengan pengambilan elemen individual, tetapi mengekstraksi sebuah irisan mungkin tidak masuk akal. (Salah satu contohnya adalah antarmuka

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
_26 di Model Objek Dokumen W3C. )

3. 3. 1. Penyesuaian dasar

objek. __baru__(cls[ , . ...])

Dipanggil untuk membuat instance baru dari class cls. adalah metode statis (berkasus khusus sehingga Anda tidak perlu mendeklarasikannya seperti itu) yang mengambil kelas yang diminta instance sebagai argumen pertamanya. Argumen yang tersisa adalah yang diteruskan ke ekspresi konstruktor objek (panggilan ke kelas). Nilai pengembalian harus berupa instance objek baru (biasanya instance cls)

Implementasi tipikal membuat instance baru dari kelas dengan memanggil metode superclass menggunakan

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
30 dengan argumen yang sesuai dan kemudian memodifikasi instance yang baru dibuat seperlunya sebelum mengembalikannya

Jika dipanggil selama konstruksi objek dan mengembalikan instance cls, maka metode instance baru akan dipanggil seperti

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
33, di mana self adalah instance baru dan argumen yang tersisa sama dengan yang diteruskan ke konstruktor objek

Jika tidak mengembalikan instance cls, maka metode instance baru tidak akan dipanggil

dimaksudkan terutama untuk memungkinkan subclass dari jenis yang tidak dapat diubah (seperti int, str, atau tuple) untuk menyesuaikan pembuatan instance. Itu juga biasanya diganti dalam metaclass khusus untuk menyesuaikan pembuatan kelas

objek. __init__(diri sendiri[ , . ...])

Dipanggil setelah instance dibuat (oleh ), tetapi sebelum dikembalikan ke pemanggil. Argumen adalah yang diteruskan ke ekspresi konstruktor kelas. Jika kelas dasar memiliki metode, metode kelas turunan, jika ada, harus secara eksplisit memanggilnya untuk memastikan inisialisasi yang tepat dari bagian kelas dasar dari instance; .

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
_40

Karena dan bekerja sama dalam membangun objek (untuk membuatnya, dan menyesuaikannya), tidak ada nilai non-

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8 yang dapat dikembalikan oleh ;

objek. __del__(diri sendiri)

Dipanggil saat instance akan dihancurkan. Ini juga disebut finalizer atau (salah) destruktor. Jika kelas dasar memiliki metode, metode kelas turunan, jika ada, harus secara eksplisit memanggilnya untuk memastikan penghapusan bagian kelas dasar dari instance dengan benar.

Itu mungkin (walaupun tidak disarankan. ) untuk metode menunda penghancuran instance dengan membuat referensi baru untuknya. Ini disebut kebangkitan objek. Itu tergantung pada implementasi apakah disebut untuk kedua kalinya ketika objek yang dibangkitkan akan dihancurkan;

Tidak ada jaminan bahwa metode dipanggil untuk objek yang masih ada saat juru bahasa keluar

Catatan

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
_53 tidak langsung memanggil
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
54 — yang pertama mengurangi jumlah referensi untuk
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
0 per satu, dan yang terakhir hanya dipanggil ketika jumlah referensi
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
0 mencapai nol

Detail implementasi CPython. Dimungkinkan untuk siklus referensi untuk mencegah jumlah referensi suatu objek menjadi nol. Dalam hal ini, siklus nantinya akan terdeteksi dan dihapus oleh. Penyebab umum dari siklus referensi adalah ketika pengecualian telah ditangkap dalam variabel lokal. Lokal frame kemudian mereferensikan pengecualian, yang mereferensikan traceback-nya sendiri, yang mereferensikan lokal dari semua frame yang tertangkap di traceback

Lihat juga

Dokumentasi untuk modul

Peringatan

Karena keadaan genting di mana metode dipanggil, pengecualian yang terjadi selama eksekusi mereka diabaikan, dan peringatan dicetak ke

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
29 sebagai gantinya. Secara khusus

  • dapat dipanggil saat kode arbitrer dieksekusi, termasuk dari utas arbitrer apa pun. Jika perlu mengambil kunci atau memanggil sumber daya pemblokiran lainnya, itu mungkin menemui jalan buntu karena sumber daya mungkin sudah diambil oleh kode yang terganggu untuk dieksekusi

  • dapat dieksekusi selama penonaktifan juru bahasa. Akibatnya, variabel global yang perlu diakses (termasuk modul lain) mungkin telah dihapus atau disetel ke

    class A:
        x = C()  # Automatically calls: x.__set_name__(A, 'x')
    
    8. Python menjamin bahwa global yang namanya dimulai dengan satu garis bawah akan dihapus dari modulnya sebelum global lainnya dihapus;

objek. __repr__(diri sendiri)

Dipanggil oleh fungsi bawaan untuk menghitung representasi string "resmi" dari suatu objek. Jika memungkinkan, ini akan terlihat seperti ekspresi Python yang valid yang dapat digunakan untuk membuat ulang objek dengan nilai yang sama (diberikan lingkungan yang sesuai). Jika ini tidak memungkinkan, string dalam bentuk

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
67 harus dikembalikan. Nilai yang dikembalikan harus berupa objek string. Jika suatu kelas mendefinisikan tetapi tidak , maka juga digunakan ketika representasi string "informal" dari instance kelas itu diperlukan

Ini biasanya digunakan untuk debugging, jadi penting agar representasi kaya informasi dan tidak ambigu

objek. __str__(diri sendiri)

Dipanggil oleh dan fungsi bawaan dan untuk menghitung representasi string "informal" atau yang dapat dicetak dengan baik dari suatu objek. Nilai yang dikembalikan harus berupa objek

Metode ini berbeda dari yang tidak ada harapan yang mengembalikan ekspresi Python yang valid. representasi yang lebih nyaman atau ringkas dapat digunakan

Implementasi default ditentukan oleh panggilan tipe bawaan

objek. __bytes__(self)

Dipanggil oleh untuk menghitung representasi byte-string dari suatu objek. Ini harus mengembalikan objek

objek. __format__(diri sendiri , format_spec)

Dipanggil oleh fungsi bawaan, dan dengan ekstensi, evaluasi dan metode, untuk menghasilkan representasi string "terformat" dari suatu objek. Argumen format_spec adalah string yang berisi deskripsi opsi pemformatan yang diinginkan. Interpretasi argumen format_spec tergantung pada tipe implement , namun sebagian besar kelas akan mendelegasikan pemformatan ke salah satu tipe bawaan, atau menggunakan sintaks opsi pemformatan serupa

Lihat untuk deskripsi sintaks pemformatan standar

Nilai yang dikembalikan harus berupa objek string

Berubah di versi 3. 4. Metode __format__ dari

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
76 itu sendiri memunculkan if melewati string yang tidak kosong.

Berubah di versi 3. 7.

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
_84 sekarang setara dengan
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
85 bukan
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
86.

objek. __lt__(diri sendiri , lainnya . )object.__le__(diri sendiri , lainnya . )object.__eq__(diri sendiri , lainnya . )object.__ne__(diri sendiri , lainnya . )object.__gt__(diri sendiri , lainnya . )object.__ge__(diri sendiri , lainnya)

Inilah yang disebut metode "perbandingan kaya". Korespondensi antara simbol operator dan nama metode adalah sebagai berikut.

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
87 Panggilan
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
88,
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
89 Panggilan
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
90,
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
91 Panggilan
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
92,
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
93 Panggilan ________4______94,
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
95 Panggilan __________0 ______0 ____5, dan ________4, ________4, ________4, ________4, ________4, ________.

Metode perbandingan kaya dapat mengembalikan singleton

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
9 jika tidak menerapkan operasi untuk pasangan argumen tertentu. Berdasarkan konvensi,
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
1 dan
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
2 dikembalikan untuk perbandingan yang berhasil. Namun, metode ini dapat mengembalikan nilai apa pun, jadi jika operator pembanding digunakan dalam konteks Boolean (mis. g. , dalam kondisi pernyataan
class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
_02), Python akan memanggil nilai untuk menentukan apakah hasilnya benar atau salah

Secara default,

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
_76 mengimplementasikan dengan menggunakan
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
7, mengembalikan
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
9 dalam kasus perbandingan palsu.
class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
_08. Untuk , secara default mendelegasikan ke dan membalikkan hasilnya kecuali
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
9. Tidak ada hubungan tersirat lainnya di antara operator pembanding atau implementasi default; . Untuk secara otomatis menghasilkan operasi pengurutan dari satu operasi root, lihat

Lihat paragraf untuk beberapa catatan penting tentang membuat objek yang mendukung operasi perbandingan khusus dan dapat digunakan sebagai kunci kamus

Tidak ada versi argumen yang ditukar dari metode ini (untuk digunakan ketika argumen kiri tidak mendukung operasi tetapi argumen kanan mendukung); . Jika operan memiliki tipe yang berbeda, dan tipe operan kanan adalah subkelas langsung atau tidak langsung dari tipe operan kiri, metode yang direfleksikan dari operan kanan memiliki prioritas, jika tidak, metode operan kiri memiliki prioritas. Subklas virtual tidak dipertimbangkan

objek. __hash__(diri sendiri)

Dipanggil oleh fungsi bawaan dan untuk operasi pada anggota koleksi hash termasuk , , dan. The

class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
15 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))

Catatan

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 hook
31

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 hook
40 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 hook
41 implies both that
class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
42 and
class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
43

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 hook
51

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 hook
54

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 hook
56 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 hook
51 call

Catatan

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 hook
03; should return
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
1 or
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
2. 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 hook
68) for class instances

object. __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 hook
72; 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. (This is an intentional asymmetry between and . ) 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. If the class also defines , the latter will not be called unless either calls it explicitly or raises an . 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 hook
85

Catatan

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"):
    pass
79 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"):
    pass
80 and
class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
88

object. __setattr__(self , name , value)

Dipanggil saat penugasan atribut dicoba. 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 hook
90

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 hook
91 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"):
    pass
80,
class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
88,
class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
94

object. __delattr__(self , name)

Like but for attribute deletion instead of assignment. 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 hook
96 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 hook
97 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"):
    pass
80 and
class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
88

object. __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):
    pass
02 and
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
03 can be also used to customize access to module attributes. The
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
02 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):
    pass
02 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__ = VerboseModule
19 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):
    pass
03 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"):
    pass
22 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

Catatan

Defining module

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
02 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"):
    pass
22 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"):
    pass
22 module attribute is now writable.

New in version 3. 7.

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
02 and
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
03 module attributes.

Lihat juga

PEP 562 - Module __getattr__ and __dir__

Describes the

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
02 and
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
03 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)

Dipanggil untuk menghapus atribut pada instance dari kelas pemilik

Atribut

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
_28 ditafsirkan oleh modul sebagai menentukan kelas di mana objek ini didefinisikan (pengaturan ini tepat dapat membantu dalam introspeksi runtime dari atribut kelas dinamis). Untuk callable, ini mungkin menunjukkan bahwa turunan dari tipe yang diberikan (atau subkelas) diharapkan atau diperlukan sebagai argumen posisi pertama (misalnya, CPython menyetel atribut ini untuk metode tidak terikat yang diimplementasikan dalam C)

3. 3. 2. 3. Memanggil Deskriptor

Secara umum, deskriptor adalah atribut objek dengan "perilaku pengikatan", atribut yang akses atributnya telah diganti oleh metode dalam protokol deskriptor. , , dan. Jika salah satu dari metode tersebut didefinisikan untuk objek, dikatakan sebagai deskriptor

Perilaku default untuk akses atribut adalah mendapatkan, menyetel, atau menghapus atribut dari kamus objek. Misalnya,

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
_33 memiliki rantai pencarian yang dimulai dengan
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
34, lalu
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
35, dan berlanjut hingga kelas dasar
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
36 tidak termasuk metaclass

Namun, jika nilai yang dicari adalah objek yang mendefinisikan salah satu metode deskriptor, maka Python dapat mengesampingkan perilaku default dan memanggil metode deskriptor sebagai gantinya. Di mana ini terjadi dalam rantai prioritas tergantung pada metode deskriptor mana yang didefinisikan dan bagaimana mereka dipanggil

Titik awal untuk pemanggilan deskriptor adalah pengikatan,

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
33. Bagaimana argumen disusun tergantung pada
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
0

Panggilan langsung

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):
    pass
39

Instance Binding

If binding to an object instance,

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
33 is transformed into the call.
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
41

Class Binding

If binding to a class,

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
42 is transformed into the call.
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
43

Super Binding

A dotted lookup such as

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
44 searches
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
45 for a base class
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
46 following
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
47 and then returns
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
48. 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"):
    pass
0 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 hook
73, 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):
    pass
26 and/or
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
27, 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 hook
73 and
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
26, 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 hook
73 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 hook
73 and
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
26 (and/or
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
27) 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

3. 3. 2. 4. 1. Notes on using __slots__
  • 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__ declaration

  • Without 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):
    pass
84 solely applies to future subclasses of the class defining the method

classmethod object. __init_subclass__(cls)

This method is called whenever the containing class is subclassed. cls is then the new subclass. 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):
    pass
84. For compatibility with other classes using
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
84, 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):
    pass
87 does nothing, but raises an error if it is called with any arguments

Catatan

The metaclass hint

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
88 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):
    pass
84 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):
    pass
90

New in version 3. 6

When a class is created,

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
91 scans the class variables and makes callbacks to those with a hook

object. __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):
    pass
96

The class creation process can be customized by passing the

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
88 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):
    pass
98 and
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
99 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;

  • badan kelas dieksekusi;

  • 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

Lihat juga

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):
    pass
90) 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 hook
2

3. 3. 3. 4. Mempersiapkan ruang nama kelas

Once the appropriate metaclass has been identified, then the class namespace is prepared. Jika metaclass memiliki

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 atribut, itu disebut sebagai
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 (di mana argumen kata kunci tambahan, jika ada, berasal dari definisi kelas). Metode
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 harus diterapkan sebagai a. Namespace yang dikembalikan oleh
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 diteruskan ke
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, tetapi ketika objek kelas terakhir dibuat, namespace disalin ke
class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
25 baru

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

Lihat juga

PEP 3115 - Metaclasses in Python 3000

Introduced 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"):
    pass
22 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"):
    pass
22 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"):
    pass
22 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 and later, 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"):
    pass
22 cell is passed to the metaclass as 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"
        )
28 entry in the class namespace. 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

  1. 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;

  2. 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;

  3. 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

Lihat juga

PEP 3135 - New super

Describes 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"):
    pass
22 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"
        )
43

class. __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

Lihat juga

PEP 3119 - Introducing Abstract Base Classes

Includes 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

Lihat juga

PEP 484 - Type Hints

Introducing Python’s framework for type annotations

Documentation for objects representing parameterized generic classes

, and

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"
        )
54

classmethod object. __class_getitem__(cls , key)

Return an object representing the specialization of a generic class by type arguments found in key

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. As such, there is no need for it to be decorated with when it is defined

3. 3. 5. 1. The purpose of __class_getitem__

The purpose of is to allow runtime parameterization of standard-library generic classes in order to more easily apply to these classes

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

Custom implementations of on classes defined outside of the standard library may not be understood by third-party type-checkers such as mypy. Using

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 on any class for purposes other than type hinting is discouraged

3. 3. 5. 2. __class_getitem__ versus __getitem__

Usually, the of an object using square brackets will call the instance method defined on the object’s class. However, if the object being subscribed is itself a class, the class method may be called instead.

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 should return a object if it is properly defined

Presented with 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"
        )
66, the Python interpreter follows something like the following process to decide whether or should be called

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"
        )

In Python, all classes are themselves instances of other classes. The class of a class is known as that class’s , and most classes have the class as their metaclass. 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)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>

However, if a class has a custom metaclass that defines , subscribing the class may result in different behaviour. An example of this can be found in the module

>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>

Lihat juga

PEP 560 - Core Support for typing module and generic types

Introducing , and outlining when a results in

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 being called instead of

3. 3. 6. Emulating callable objects

object. __call__(self[ , args. ])

Called when the instance is “called” as a function; if this method is defined,

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"
        )
81 roughly translates 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"
        )
82

3. 3. 7. Emulating container types

The following methods can be defined to implement container objects. Containers usually are (such as or ) or (like ), but can represent other containers as well. The first set of methods is used either to emulate a sequence or to emulate a mapping; the difference is that for a sequence, the allowable keys should be the integers k for which

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"
        )
86 where N is the length of the sequence, or objects, which define a range of items. It is also recommended that mappings provide the methods
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, 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"
        )
97 behaving similar to those for Python’s standard objects. The module provides a to help create those methods from a base set of , , , 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"
        )
88. Mutable sequences should provide methods
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
05,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
06,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
07,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
08,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
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)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
11,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
12 and
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
13, like Python standard objects. Terakhir, tipe urutan harus mengimplementasikan penjumlahan (artinya penggabungan) dan perkalian (artinya pengulangan) dengan mendefinisikan metode , , , , dan dijelaskan di bawah; . 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)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
22 operator; for mappings,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
22 should search the mapping’s keys; for sequences, it should search through the values. It is further recommended that both mappings and sequences implement the method to allow efficient iteration through the container; for mappings,
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
21 should iterate through the object’s keys; for sequences, it should iterate through the values

object. __len__(self)

Called to implement the built-in function . Should return the length of the object, an integer

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. Also, an object that doesn’t define a method and whose method returns zero is considered to be false in a Boolean context

CPython implementation detail. In CPython, the length is required to be at most . If the length is larger than

>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
30 some features (such as ) may raise . To prevent raising
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
33 by truth value testing, an object must define a method

object. __length_hint__(self)

Dipanggil untuk mengimplementasikan. Harus mengembalikan perkiraan panjang objek (yang mungkin lebih besar atau lebih kecil dari panjang sebenarnya). The length must be an integer

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. The return value may also be , which is treated the same as if the
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
39 method didn’t exist at all. This method is purely an optimization and is never required for correctness

Baru di versi 3. 4

Catatan

Slicing is done exclusively with the following three methods. A call like

a[1:2] = b

diterjemahkan ke

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
0

Dan seterusnya. Item irisan yang hilang selalu diisi dengan

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8

objek. __getitem__(diri , kunci)

Dipanggil untuk melaksanakan evaluasi

>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
_41. Untuk tipe, kunci yang diterima harus bilangan bulat dan objek irisan. Perhatikan bahwa interpretasi khusus dari indeks negatif (jika kelas ingin meniru suatu tipe) tergantung pada metodenya. Jika kunci dari jenis yang tidak sesuai, dapat dimunculkan; . Untuk type, jika key hilang (tidak ada di container), sebaiknya dinaikkan

Catatan

loop berharap an akan dinaikkan untuk indeks ilegal untuk memungkinkan deteksi yang tepat dari akhir urutan

Catatan

Saat sebuah kelas, metode kelas khusus dapat dipanggil alih-alih

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
06. Lihat untuk detail lebih lanjut

objek. __setitem__(diri , kunci, value)

Dipanggil untuk mengimplementasikan tugas ke

>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
_41. Catatan yang sama untuk. Ini seharusnya hanya diimplementasikan untuk pemetaan jika objek mendukung perubahan nilai untuk kunci, atau jika kunci baru dapat ditambahkan, atau untuk urutan jika elemen dapat diganti. Pengecualian yang sama harus dimunculkan untuk nilai kunci yang tidak tepat seperti untuk metode

objek. __delitem__(diri , kunci)

Dipanggil untuk menerapkan penghapusan ________31______41. Catatan yang sama untuk. Ini seharusnya hanya diterapkan untuk pemetaan jika objek mendukung penghapusan kunci, atau untuk urutan jika elemen dapat dihapus dari urutan. Pengecualian yang sama harus dimunculkan untuk nilai kunci yang tidak tepat seperti untuk metode

objek. __hilang__(diri , kunci)

Dipanggil oleh. untuk mengimplementasikan

>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
41 untuk subkelas dict saat kunci tidak ada dalam kamus

objek. __iter__(diri sendiri)

Metode ini dipanggil ketika diperlukan untuk wadah. Metode ini harus mengembalikan objek iterator baru yang dapat mengulangi semua objek dalam wadah. Untuk pemetaan, itu harus beralih ke kunci wadah

objek. __terbalik__(diri sendiri)

Dipanggil (jika ada) oleh built-in untuk mengimplementasikan iterasi terbalik. Itu harus mengembalikan objek iterator baru yang mengulang semua objek dalam wadah dalam urutan terbalik

Jika metode tidak disediakan, built-in akan kembali menggunakan protokol urutan ( dan ). Objek yang mendukung protokol sekuens seharusnya hanya menyediakan jika mereka dapat menyediakan implementasi yang lebih efisien daripada yang disediakan oleh

Operator uji keanggotaan ( dan ) biasanya diimplementasikan sebagai iterasi melalui wadah. Namun, objek container dapat menyediakan metode khusus berikut dengan implementasi yang lebih efisien, yang juga tidak mengharuskan objek dapat diulang

objek. __berisi__(diri , item)

Dipanggil untuk mengimplementasikan operator uji keanggotaan. Harus mengembalikan true jika item ada di dalam diri, false jika sebaliknya. Untuk objek pemetaan, ini harus mempertimbangkan kunci pemetaan daripada nilai atau pasangan kunci-item

Untuk objek yang tidak terdefinisi , pengujian keanggotaan pertama kali mencoba iterasi melalui , kemudian protokol iterasi urutan lama melalui , lihat

3. 3. 8. Mengemulasi tipe numerik

Metode berikut dapat didefinisikan untuk meniru objek numerik. Metode yang sesuai dengan operasi yang tidak didukung oleh jenis angka tertentu yang diterapkan (mis. g. , operasi bitwise untuk bilangan non-integral) harus dibiarkan tidak terdefinisi

objek. __add__(diri sendiri , lainnya . )object.__sub__(diri sendiri , lainnya . )object.__mul__(diri sendiri , lainnya . )object.__matmul__(diri sendiri , lainnya . )object.__truediv__(diri sendiri , lainnya . )object.__floordiv__(diri sendiri , lainnya . )object.__mod__(diri sendiri , lainnya . )object.__divmod__(self , other)object. __pow__(self , other[ , modulo])object. __lshift__(self , other)object. __rshift__(self , other)object. __and__(self , other)object. __xor__(self , other)object. __or__(self , other)

These methods are called to implement the binary arithmetic operations (

>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
71,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
72,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
73,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
74,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
75,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
76,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
77, , ,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
80,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
81,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
82,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
83,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
84,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
85). For instance, to evaluate the expression
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
86, where x is an instance of a class that has an method,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
88 is called. The method should be the equivalent to using and ; it should not be related to . Note that should be defined to accept an optional third argument if the ternary version of the built-in function is to be supported

If one of those methods does not support the operation with the supplied arguments, it should return

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
9

object. __radd__(self , other)object. __rsub__(self , other)object. __rmul__(self , other)object. __rmatmul__(self , other)object. __rtruediv__(self , other)object. __rfloordiv__(self , other)object. __rmod__(self , other)object. __rdivmod__(self , other)object. __rpow__(self , other[ , modulo])object. __rlshift__(self , other)object. __rrshift__(self , other)object. __rand__(diri sendiri , lainnya . )object.__rxor__(self , other)object. __ror__(self , other)

These methods are called to implement the binary arithmetic operations (

>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
71,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
72,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
73,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
74,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
75,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
76,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
77, , ,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
80,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
81,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
82,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
83,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
84,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
85) with reflected (swapped) operands. These functions are only called if the left operand does not support the corresponding operation and the operands are of different types. For instance, to evaluate the expression
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
11, where y is an instance of a class that has an method,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
13 is called if
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
14 returns NotImplemented

Note that ternary will not try calling (the coercion rules would become too complicated)

Catatan

If the right operand’s type is a subclass of the left operand’s type and that subclass provides a different implementation of the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations

object. __iadd__(diri sendiri , lainnya . )object.__isub__(self , other)object. __imul__(self , other)object. __imatmul__(diri sendiri , lainnya . )object.__itruediv__(diri sendiri , lainnya . )object.__floordiv__(diri sendiri , lainnya . )object.__imod__(diri sendiri , lainnya . )object.__ipow__(diri sendiri , lainnya . [, modulo])object.__ilshift__(diri sendiri , lainnya . )object.__irshift__(diri sendiri , lainnya . )object.__iand__(diri sendiri , lainnya . )object.__ixor__(diri sendiri , lainnya . )object.__ior__(diri sendiri , lainnya)

These methods are called to implement the augmented arithmetic assignments (

>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
17,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
18,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
19,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
20,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
21,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
22,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
23,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
24,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
25,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
26,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
27,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
28,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
29). Metode-metode ini harus mencoba melakukan operasi di tempat (memodifikasi diri) dan mengembalikan hasilnya (yang bisa, tetapi tidak harus, diri sendiri). Jika metode tertentu tidak ditentukan, penugasan yang diperbesar kembali ke metode normal. Misalnya, jika x adalah turunan dari kelas dengan metode,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
31 setara dengan
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
32. Jika tidak,
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
33 dan
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
34 dipertimbangkan, seperti evaluasi
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
86. Dalam situasi tertentu, penugasan yang diperbesar dapat menghasilkan kesalahan yang tidak terduga (lihat ), tetapi perilaku ini sebenarnya adalah bagian dari model data

objek. __neg__(diri)objek. __pos__(diri)objek. __abs__(diri)objek. __balik__(diri sendiri)

Dipanggil untuk mengimplementasikan operasi aritmatika unary (

>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
72,
>>> # list has class "type" as its metaclass, like most classes:
>>> type(list)
<class 'type'>
>>> 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])
<class 'types.GenericAlias'>
71, dan
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
39)

objek. __kompleks__(diri)objek. __int__(diri)objek. __float__(diri sendiri)

Dipanggil untuk mengimplementasikan fungsi bawaan, dan. Harus mengembalikan nilai dari jenis yang sesuai

objek. __indeks__(diri sendiri)

Dipanggil untuk implement , dan kapan pun Python perlu mengonversi objek numerik menjadi objek integer tanpa kehilangan (seperti dalam slicing, atau dalam built-in , dan fungsi). Kehadiran metode ini menunjukkan bahwa objek numerik adalah tipe integer. Harus mengembalikan bilangan bulat

Jika , dan tidak ditentukan maka fungsi bawaan yang sesuai , dan kembali ke

objek. __bulat__(diri[ , . ndigits])object.__trunc__(diri)objek. __floor__(diri)objek. __ceil__(diri sendiri)

Dipanggil untuk mengimplementasikan fungsi bawaan dan functions , dan. Kecuali ndigit diteruskan ke

>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
_59 semua metode ini harus mengembalikan nilai objek terpotong ke (biasanya )

Fungsi bawaan kembali ke jika tidak ada atau tidak ditentukan

Berubah di versi 3. 11. Delegasi ke tidak digunakan lagi.

3. 3. 9. Dengan Manajer Konteks Pernyataan

Manajer konteks adalah objek yang menentukan konteks runtime yang akan dibuat saat mengeksekusi pernyataan. Manajer konteks menangani masuk ke, dan keluar dari, konteks runtime yang diinginkan untuk eksekusi blok kode. Pengelola konteks biasanya dipanggil menggunakan pernyataan

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
8 (dijelaskan di bagian ), tetapi juga dapat digunakan dengan langsung memanggil metode mereka

Penggunaan umum pengelola konteks termasuk menyimpan dan memulihkan berbagai jenis keadaan global, mengunci dan membuka kunci sumber daya, menutup file yang dibuka, dll.

Untuk informasi lebih lanjut tentang manajer konteks, lihat

objek. __enter__(diri sendiri)

Masukkan konteks runtime yang terkait dengan objek ini. Pernyataan tersebut akan mengikat nilai pengembalian metode ini ke target yang ditentukan dalam klausa

>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
71 dari pernyataan tersebut, jika ada

objek. __exit__(self , exc_type, exc_value, traceback)

Keluar dari konteks runtime yang terkait dengan objek ini. Parameter menjelaskan pengecualian yang menyebabkan konteks keluar. Jika konteksnya keluar tanpa pengecualian, ketiga argumen akan keluar

Jika pengecualian diberikan, dan metode ingin menekan pengecualian (mis. e. , mencegahnya disebarkan), itu harus mengembalikan nilai sebenarnya. Jika tidak, pengecualian akan diproses secara normal setelah keluar dari metode ini

Perhatikan bahwa metode tidak boleh memunculkan kembali pengecualian yang diteruskan;

Lihat juga

PEP 343 - Pernyataan "dengan".

Spesifikasi, latar belakang, dan contoh untuk pernyataan Python

3. 3. 10. Menyesuaikan argumen posisi dalam pencocokan pola kelas

Saat menggunakan nama kelas dalam suatu pola, argumen posisi dalam pola tidak diperbolehkan secara default, mis. e.

>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
75 biasanya tidak valid tanpa dukungan khusus di
class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass
98. Untuk dapat menggunakan pola semacam itu, kelas perlu mendefinisikan atribut __match_args__

objek. __match_args__

Variabel kelas ini dapat diberi tupel string. Saat kelas ini digunakan dalam pola kelas dengan argumen posisi, setiap argumen posisi akan diubah menjadi argumen kata kunci, menggunakan nilai yang sesuai di __match_args__ sebagai kata kunci. Tidak adanya atribut ini sama dengan menyetelnya ke

>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
77

Misalnya, jika

>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
78 adalah
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
79 itu berarti
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
75 setara dengan
>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
81. Perhatikan bahwa jumlah argumen dalam pola harus lebih kecil atau sama dengan jumlah elemen dalam __match_args__;

Baru di versi 3. 10

Lihat juga

PEP 634 - Pencocokan Pola Struktural

Spesifikasi untuk pernyataan Python

>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
_83

3. 3. 11. Pencarian metode khusus

Untuk kelas khusus, pemanggilan implisit dari metode khusus hanya dijamin untuk bekerja dengan benar jika didefinisikan pada tipe objek, bukan pada kamus instan objek. Perilaku itu adalah alasan mengapa kode berikut memunculkan pengecualian

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
_1

Dasar pemikiran di balik perilaku ini terletak pada sejumlah metode khusus seperti dan yang diimplementasikan oleh semua objek, termasuk objek bertipe. Jika pencarian implisit dari metode ini menggunakan proses pencarian konvensional, metode tersebut akan gagal saat dipanggil pada objek tipe itu sendiri

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
_2

Upaya yang salah untuk memanggil metode kelas yang tidak terikat dengan cara ini kadang-kadang disebut sebagai 'kebingungan metaclass', dan dihindari dengan melewati instance saat mencari metode khusus

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
_3

Selain melewati atribut instance apa pun demi kepentingan kebenaran, pencarian metode khusus implisit umumnya juga melewati metode bahkan dari metaclass objek

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
_4

Melewati mesin dengan cara ini memberikan ruang yang signifikan untuk optimalisasi kecepatan dalam penafsir, dengan mengorbankan beberapa fleksibilitas dalam penanganan metode khusus (metode khusus harus ditetapkan pada objek kelas itu sendiri agar dapat dipanggil secara konsisten oleh penafsir)

3. 4. Coroutine

3. 4. 1. Objek yang Ditunggu

Objek umumnya mengimplementasikan metode. kembali dari fungsi yang ditunggu

Catatan

Objek yang dikembalikan dari generator yang didekorasi juga dapat ditunggu, tetapi tidak diterapkan

objek. __menunggu__(diri sendiri)

Harus mengembalikan an. Harus digunakan untuk mengimplementasikan objek. Misalnya, implementasikan metode ini agar kompatibel dengan ekspresi

Catatan

Bahasa tidak membatasi jenis atau nilai objek yang dihasilkan oleh iterator yang dikembalikan oleh

>>> from enum import Enum
>>> class Menu(Enum):
..     """A breakfast menu"""
..     SPAM = 'spam'
..     BACON = 'bacon'
...
>>> # Enum classes have a custom metaclass:
>>> type(Menu)
<class 'enum.EnumMeta'>
>>> # EnumMeta defines __getitem__,
>>> # so __class_getitem__ is not called,
>>> # and the result is not a GenericAlias object:
>>> Menu['SPAM']
<Menu.SPAM: 'spam'>
>>> type(Menu['SPAM'])
<enum 'Menu'>
94, karena ini khusus untuk penerapan kerangka eksekusi asinkron (mis. g. ) yang akan mengelola objek

Baru di versi 3. 5

Lihat juga

PEP 492 untuk informasi tambahan tentang objek yang dapat ditunggu

3. 4. 2. Objek Coroutine

adalah objek. Eksekusi coroutine dapat dikontrol dengan memanggil dan mengulangi hasilnya. Saat coroutine selesai mengeksekusi dan mengembalikan, iterator raises , dan atribut pengecualian

class A:
   pass

c = C()
A.x = c                  # The hook is not called
c.__set_name__(A, 'x')   # Manually invoke the hook
94 menyimpan nilai kembalian. Jika coroutine memunculkan pengecualian, itu disebarkan oleh iterator. Coroutine tidak boleh secara langsung memunculkan pengecualian yang tidak tertangani

Coroutine juga memiliki metode yang tercantum di bawah ini, yang serupa dengan generator (lihat ). Namun, tidak seperti generator, coroutine tidak mendukung iterasi secara langsung

Berubah di versi 3. 5. 2. Menunggu coroutine lebih dari sekali.

coroutine. kirim(nilai)

Memulai atau melanjutkan eksekusi coroutine. Jika nilainya

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
_8, ini sama dengan memajukan iterator yang dikembalikan oleh. Jika nilainya bukan
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
8, metode ini didelegasikan ke metode iterator yang menyebabkan coroutine ditangguhkan. Hasilnya (nilai kembalian, , atau pengecualian lainnya) sama seperti saat mengulangi nilai kembalian ________39______88, yang dijelaskan di atas

coroutine. melempar(nilai)coroutine. melempar(ketik[ , value[, traceback]])

Memunculkan pengecualian yang ditentukan di coroutine. Metode ini mendelegasikan ke metode iterator yang menyebabkan coroutine ditangguhkan, jika memiliki metode seperti itu. Jika tidak, pengecualian akan dimunculkan pada titik penangguhan. Hasilnya (nilai kembalian, , atau pengecualian lainnya) sama seperti saat mengulangi nilai kembalian, yang dijelaskan di atas. Jika pengecualian tidak tertangkap di coroutine, pengecualian akan disebarkan kembali ke pemanggil

coroutine. tutup()

Menyebabkan coroutine membersihkan dirinya sendiri dan keluar. Jika coroutine ditangguhkan, metode ini pertama-tama didelegasikan ke metode iterator yang menyebabkan coroutine ditangguhkan, jika memiliki metode seperti itu. Kemudian naik pada titik suspensi, menyebabkan coroutine segera membersihkan dirinya sendiri. Terakhir, coroutine ditandai sebagai selesai dieksekusi, meskipun tidak pernah dimulai

Objek Coroutine ditutup secara otomatis menggunakan proses di atas saat akan dihancurkan

3. 4. 3. Iterator Asinkron

Iterator asinkron dapat memanggil kode asinkron dalam metode

a[1:2] = b
12 nya

Iterator asinkron dapat digunakan dalam pernyataan

objek. __aiter__(diri sendiri)

Harus mengembalikan objek iterator asinkron

objek. __annext__(diri sendiri)

Harus mengembalikan hasil yang dapat ditunggu dalam nilai berikutnya dari iterator. Harus menimbulkan kesalahan saat iterasi selesai

Contoh objek iterable asinkron

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
5

Baru di versi 3. 5

Berubah di versi 3. 7. Sebelum Python 3. 7, bisa mengembalikan sebuah menunggu yang akan menyelesaikan ke.

Dimulai dengan Python 3. 7, harus mengembalikan objek iterator asinkron. Mengembalikan apa pun akan menghasilkan kesalahan

3. 4. 4. Pengelola Konteks Asinkron

Manajer konteks asinkron adalah manajer konteks yang dapat menangguhkan eksekusi dalam metode ________41______18 dan

a[1:2] = b
19

Manajer konteks asinkron dapat digunakan dalam pernyataan

objek. __aenter__(diri sendiri)

Secara semantik mirip dengan , satu-satunya perbedaan adalah ia harus mengembalikan yang ditunggu

objek. __aexit__(self , exc_type, exc_value, traceback)

Secara semantik mirip dengan , satu-satunya perbedaan adalah ia harus mengembalikan yang ditunggu

Contoh kelas manajer konteks asinkron

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
_6

Baru di versi 3. 5

Catatan kaki

Dimungkinkan dalam beberapa kasus untuk mengubah tipe objek, dalam kondisi terkontrol tertentu. Ini umumnya bukan ide yang baik, karena dapat menyebabkan perilaku yang sangat aneh jika ditangani dengan tidak benar

Metode , , , dan memiliki penanganan khusus untuk ini;

“Tidak mendukung” di sini berarti kelas tersebut tidak memiliki metode seperti itu, atau metode mengembalikan

class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
9. Jangan setel metode ke
class A:
    x = C()  # Automatically calls: x.__set_name__(A, 'x')
_8 jika Anda ingin memaksa fallback ke metode yang direfleksikan operan yang tepat—yang sebaliknya akan memiliki efek berlawanan dengan memblokir fallback tersebut secara eksplisit

Untuk operan dengan tipe yang sama, diasumsikan bahwa jika metode yang tidak direfleksikan – seperti – gagal maka keseluruhan operasi tidak didukung, oleh karena itu metode yang direfleksikan tidak dipanggil

Untuk apa Setattr () dan Getattr () digunakan?

Python setattr() dan getattr() bergandengan tangan. Seperti yang telah kita lihat apa yang dilakukan setattr(); . Fungsi getattr() mendukung banyak parameter. to retrieve the value of an object's attribute; and if no attribute of that object is discovered, the default value is returned. The function getattr() supports many parameters.

Apa itu __ Setattr __ dengan Python?

Metode setattr() Python digunakan digunakan untuk menetapkan atribut objek nilainya .

Apa yang dilakukan Getattr () dengan Python?

Fungsi getattr() mengembalikan nilai atribut yang ditentukan dari objek yang ditentukan .

Apa yang akan terjadi jika Getattr() mencoba mengambil atribut dari objek yang tidak ada?

Metode getattr() mengembalikan nilai atribut bernama dari suatu objek. Jika tidak ditemukan, mengembalikan nilai default yang diberikan ke fungsi .