Python __new__ siêu dữ liệu

Tìm hiểu về Siêu dữ liệu trong Python là gì, Siêu dữ liệu loại, Siêu dữ liệu tùy chỉnh và so sánh giữa Siêu dữ liệu và Kế thừa

Ảnh của Grace O'Driscoll trên Bapt

Hãy nhớ rằng trong blog trước về ABC (Lớp cơ sở trừu tượng), chúng ta có thể vượt qua (metaclass=ABCMeta)?

Để hiểu được điều đó, trước tiên chúng ta cần hiểu về Lớp python (chúng ta đang nói về lớp kiểu mới)

Sự khác biệt giữa lớp kiểu cũ và kiểu mới là sự thống nhất giữa lớp và kiểu. Vì với x là một thể hiện của lớp kiểu mới, type(x) is x.__class__ , trong khi với kiểu cũ, type(x) is type <'instance'>

>>> class Example:
.. pass
>>> e = Example()
>>> e.__class__
<class '__main__.Example'>
>>> type(e)
<class '__main__.Example'>
>>> e.__class__ is type(Example)
True

Loại siêu dữ liệu

Trong python, type là một siêu dữ liệu, trong đó tất cả các lớp (kiểu mới) được bắt nguồn từ

Theo mặc định, các lớp được xây dựng bằng cách sử dụng type(). Nội dung lớp được thực thi trong một không gian tên mới và tên lớp được liên kết cục bộ với kết quả của

1. with name arg>>> Example = type('Example', (), {})

>>> x = Example()
>>> x
<__main__.Example object at 0x1088c78e0>
2. with name and base (As tuple)and dict>>> AnotherExample = type('AnotherExample', (Example,), dict(attr=1))

>>> x = AnotherExample()
>>> x.attr
1
>>> x.__class__
<class '__main__.AnotherExample'>
>>> x.__class__.__bases__
(<class '__main__.Example'>,)
0

lớp

1. with name arg>>> Example = type('Example', (), {})

>>> x = Example()
>>> x
<__main__.Example object at 0x1088c78e0>
2. with name and base (As tuple)and dict>>> AnotherExample = type('AnotherExample', (Example,), dict(attr=1))

>>> x = AnotherExample()
>>> x.attr
1
>>> x.__class__
<class '__main__.AnotherExample'>
>>> x.__class__.__bases__
(<class '__main__.Example'>,)
1(tên, căn cứ, chính tả)

Với một đối số, trả về loại đối tượng. Giá trị trả về là một đối tượng kiểu và thường là cùng một đối tượng được trả về bởi

1. with name arg>>> Example = type('Example', (), {})

>>> x = Example()
>>> x
<__main__.Example object at 0x1088c78e0>
2. with name and base (As tuple)and dict>>> AnotherExample = type('AnotherExample', (Example,), dict(attr=1))

>>> x = AnotherExample()
>>> x.attr
1
>>> x.__class__
<class '__main__.AnotherExample'>
>>> x.__class__.__bases__
(<class '__main__.Example'>,)
2

Với ba đối số, trả về một đối tượng kiểu mới. Đây thực chất là một dạng động của câu lệnh

1. with name arg>>> Example = type('Example', (), {})

>>> x = Example()
>>> x
<__main__.Example object at 0x1088c78e0>
2. with name and base (As tuple)and dict>>> AnotherExample = type('AnotherExample', (Example,), dict(attr=1))

>>> x = AnotherExample()
>>> x.attr
1
>>> x.__class__
<class '__main__.AnotherExample'>
>>> x.__class__.__bases__
(<class '__main__.Example'>,)
3

Chuỗi tên là tên lớp và trở thành thuộc tính

1. with name arg>>> Example = type('Example', (), {})

>>> x = Example()
>>> x
<__main__.Example object at 0x1088c78e0>
2. with name and base (As tuple)and dict>>> AnotherExample = type('AnotherExample', (Example,), dict(attr=1))

>>> x = AnotherExample()
>>> x.attr
1
>>> x.__class__
<class '__main__.AnotherExample'>
>>> x.__class__.__bases__
(<class '__main__.Example'>,)
4;

1. with name arg>>> Example = type('Example', (), {})

>>> x = Example()
>>> x
<__main__.Example object at 0x1088c78e0>
2. with name and base (As tuple)and dict>>> AnotherExample = type('AnotherExample', (Example,), dict(attr=1))

>>> x = AnotherExample()
>>> x.attr
1
>>> x.__class__
<class '__main__.AnotherExample'>
>>> x.__class__.__bases__
(<class '__main__.Example'>,)
7
1. with name arg>>> Example = type('Example', (), {})

>>> x = Example()
>>> x
<__main__.Example object at 0x1088c78e0>
2. with name and base (As tuple)and dict>>> AnotherExample = type('AnotherExample', (Example,), dict(attr=1))

>>> x = AnotherExample()
>>> x.attr
1
>>> x.__class__
<class '__main__.AnotherExample'>
>>> x.__class__.__bases__
(<class '__main__.Example'>,)
8
1. with name arg>>> Example = type('Example', (), {})

>>> x = Example()
>>> x
<__main__.Example object at 0x1088c78e0>
2. with name and base (As tuple)and dict>>> AnotherExample = type('AnotherExample', (Example,), dict(attr=1))

>>> x = AnotherExample()
>>> x.attr
1
>>> x.__class__
<class '__main__.AnotherExample'>
>>> x.__class__.__bases__
(<class '__main__.Example'>,)
9

Gọi type() theo cách này sẽ tạo ra một phiên bản mới của siêu dữ liệu type, hay còn gọi là một lớp mới

1. with name arg>>> Example = type('Example', (), {})

>>> x = Example()
>>> x
<__main__.Example object at 0x1088c78e0>
2. with name and base (As tuple)and dict>>> AnotherExample = type('AnotherExample', (Example,), dict(attr=1))

>>> x = AnotherExample()
>>> x.attr
1
>>> x.__class__
<class '__main__.AnotherExample'>
>>> x.__class__.__bases__
(<class '__main__.Example'>,)

Metaclass hoạt động như thế nào

Vì vậy, bạn có thể thấy Metaclass là một giải pháp thay thế để tạo lớp, nhưng bạn cũng nên nhớ rằng để tạo một lớp, chúng ta chỉ có thể sử dụng tính kế thừa. Vậy tại sao chúng ta cần Metaclass?

Đầu tiên, Metaclass không thực sự nằm trong lĩnh vực lập trình hướng đối tượng. Nó không phải là một phần của hệ thống phân cấp lớp của đối tượng trong khi các lớp cơ sở là. Siêu dữ liệu sẽ không xuất hiện trong MRO, nghĩa là nếu một đối tượng thực hiện


>>> __metaclass__ = type
>>>
>>> class A:
.. pass
>>> a = A()

>>> a
<__main__.A object at 0x4f5cf3>
>>> type(a)
<class '__main__.A'>
>>> A
<class '__main__.A'>
>>> type(A)
<type 'type'>
2 thì nó sẽ không tìm kiếm siêu dữ liệu cho phương thức này


>>> __metaclass__ = type
>>>
>>> class A:
.. pass
>>> a = A()

>>> a
<__main__.A object at 0x4f5cf3>
>>> type(a)
<class '__main__.A'>
>>> A
<class '__main__.A'>
>>> type(A)
<type 'type'>

Do đó, Metaclass được sử dụng trong các lớp xây dựng (__call__) và định nghĩa (ba lớp còn lại bên dưới)

Có một số phương thức ma thuật mà Metaclasses sử dụng để thao tác với một lớp

Tạo lớp học


  • >>> __metaclass__ = type
    >>>
    >>> class A:
    .. pass
    >>> a = A()

    >>> a
    <__main__.A object at 0x4f5cf3>
    >>> type(a)
    <class '__main__.A'>
    >>> A
    <class '__main__.A'>
    >>> type(A)
    <type 'type'>
    3. để khởi tạo một lớp;

  • >>> __metaclass__ = type
    >>>
    >>> class A:
    .. pass
    >>> a = A()

    >>> a
    <__main__.A object at 0x4f5cf3>
    >>> type(a)
    <class '__main__.A'>
    >>> A
    <class '__main__.A'>
    >>> type(A)
    <type 'type'>
    4. để bắt đầu các giá trị sau khi phiên bản được tạo;

  • >>> __metaclass__ = type
    >>>
    >>> class A:
    .. pass
    >>> a = A()

    >>> a
    <__main__.A object at 0x4f5cf3>
    >>> type(a)
    <class '__main__.A'>
    >>> A
    <class '__main__.A'>
    >>> type(A)
    <type 'type'>
    5. để xác định không gian tên lớp trong ánh xạ lưu trữ các thuộc tính, có nghĩa là, thuộc tính

    >>> __metaclass__ = type
    >>>
    >>> class A:
    .. pass
    >>> a = A()

    >>> a
    <__main__.A object at 0x4f5cf3>
    >>> type(a)
    <class '__main__.A'>
    >>> A
    <class '__main__.A'>
    >>> type(A)
    <type 'type'>
    6 được chuyển vào siêu dữ liệu các phương thức

    >>> __metaclass__ = type
    >>>
    >>> class A:
    .. pass
    >>> a = A()

    >>> a
    <__main__.A object at 0x4f5cf3>
    >>> type(a)
    <class '__main__.A'>
    >>> A
    <class '__main__.A'>
    >>> type(A)
    <type 'type'>
    3 và

    >>> __metaclass__ = type
    >>>
    >>> class A:
    .. pass
    >>> a = A()

    >>> a
    <__main__.A object at 0x4f5cf3>
    >>> type(a)
    <class '__main__.A'>
    >>> A
    <class '__main__.A'>
    >>> type(A)
    <type 'type'>
    4 chính xác là cùng một đối tượng được trả về bởi

    >>> __metaclass__ = type
    >>>
    >>> class A:
    .. pass
    >>> a = A()

    >>> a
    <__main__.A object at 0x4f5cf3>
    >>> type(a)
    <class '__main__.A'>
    >>> A
    <class '__main__.A'>
    >>> type(A)
    <type 'type'>
    5 , được gọi trước các phương thức bên dưới

Tạo một thể hiện của lớp

  • class ExampleMeta(type): @classmethod
    def __prepare__(metacls, cls, bases):
    print(f”Metacls: {metacls} \n cls: {cls} \n bases: {bases}\n”)
    print(f”Calling __prepare__ method of {super()}\n”)
    return super().__prepare__(cls, bases)
    def __new__(metacls, cls, bases, dict):
    print(f”Calling __new__ method of {super()}\n”)
    return super().__new__(metacls, cls, bases, dict)
    def __init__(self, cls, bases, dict):
    print(f”Calling __init__ method of {super()}\n”)
    super().__init__(cls, bases,dict)

    def __call__(self, *args, **kwargs):
    print(f”Calling __call__ method of {super()}\n”)
    return super().__call__(*args, **kwargs)
    class A(metaclass=ExampleMeta):
    def __init__(self):
    print(“This is when the new class instance gets created\n”)
    print(f”Calling __init__ method of {self}”)
    ===============>AFTER EXECUTION OF ABOVE
    Metacls: <class '__main__.ExampleMeta'>
    cls: A
    bases: ()
    Calling __prepare__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __new__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __init__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>----------------------------------------------------------a = A()
    ===============>AFTER EXECUTION OF ABOVE
    Calling __call__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>This is when the new class instance gets createdCalling __init__ method of <__main__.A object at 0x7f1160225d60>
    0. gọi khi tạo một thể hiện của lớp, được gọi sau các phương thức

    >>> __metaclass__ = type
    >>>
    >>> class A:
    .. pass
    >>> a = A()

    >>> a
    <__main__.A object at 0x4f5cf3>
    >>> type(a)
    <class '__main__.A'>
    >>> A
    <class '__main__.A'>
    >>> type(A)
    <type 'type'>
    3 và

    >>> __metaclass__ = type
    >>>
    >>> class A:
    .. pass
    >>> a = A()

    >>> a
    <__main__.A object at 0x4f5cf3>
    >>> type(a)
    <class '__main__.A'>
    >>> A
    <class '__main__.A'>
    >>> type(A)
    <type 'type'>
    4, có nghĩa là không giống như hai phương thức này được gọi tại thời điểm tạo lớp,
    class ExampleMeta(type): @classmethod
    def __prepare__(metacls, cls, bases):
    print(f”Metacls: {metacls} \n cls: {cls} \n bases: {bases}\n”)
    print(f”Calling __prepare__ method of {super()}\n”)
    return super().__prepare__(cls, bases)
    def __new__(metacls, cls, bases, dict):
    print(f”Calling __new__ method of {super()}\n”)
    return super().__new__(metacls, cls, bases, dict)
    def __init__(self, cls, bases, dict):
    print(f”Calling __init__ method of {super()}\n”)
    super().__init__(cls, bases,dict)

    def __call__(self, *args, **kwargs):
    print(f”Calling __call__ method of {super()}\n”)
    return super().__call__(*args, **kwargs)
    class A(metaclass=ExampleMeta):
    def __init__(self):
    print(“This is when the new class instance gets created\n”)
    print(f”Calling __init__ method of {self}”)
    ===============>AFTER EXECUTION OF ABOVE
    Metacls: <class '__main__.ExampleMeta'>
    cls: A
    bases: ()
    Calling __prepare__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __new__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __init__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>----------------------------------------------------------a = A()
    ===============>AFTER EXECUTION OF ABOVE
    Calling __call__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>This is when the new class instance gets createdCalling __init__ method of <__main__.A object at 0x7f1160225d60>
    0 được gọi khi lớp đã tạo được gọi để khởi tạo một thể hiện mới của lớp

Các phương thức này có thể được ghi đè trong Metaclass tùy chỉnh để cung cấp các lớp có hành vi mặc định khác với hành vi của type như minh chứng bên dưới

class ExampleMeta(type): @classmethod
def __prepare__(metacls, cls, bases):
print(f”Metacls: {metacls} \n cls: {cls} \n bases: {bases}\n”)
print(f”Calling __prepare__ method of {super()}\n”)
return super().__prepare__(cls, bases)
def __new__(metacls, cls, bases, dict):
print(f”Calling __new__ method of {super()}\n”)
return super().__new__(metacls, cls, bases, dict)
def __init__(self, cls, bases, dict):
print(f”Calling __init__ method of {super()}\n”)
super().__init__(cls, bases,dict)

def __call__(self, *args, **kwargs):
print(f”Calling __call__ method of {super()}\n”)
return super().__call__(*args, **kwargs)
class A(metaclass=ExampleMeta):
def __init__(self):
print(“This is when the new class instance gets created\n”)
print(f”Calling __init__ method of {self}”)
===============>AFTER EXECUTION OF ABOVE
Metacls: <class '__main__.ExampleMeta'>
cls: A
bases: ()
Calling __prepare__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __new__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __init__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>----------------------------------------------------------a = A()
===============>AFTER EXECUTION OF ABOVE
Calling __call__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>This is when the new class instance gets createdCalling __init__ method of <__main__.A object at 0x7f1160225d60>

Như bạn có thể thấy ở trên, khi đọc tiêu đề và nội dung của lớp

class ExampleMeta(type): @classmethod
def __prepare__(metacls, cls, bases):
print(f”Metacls: {metacls} \n cls: {cls} \n bases: {bases}\n”)
print(f”Calling __prepare__ method of {super()}\n”)
return super().__prepare__(cls, bases)
def __new__(metacls, cls, bases, dict):
print(f”Calling __new__ method of {super()}\n”)
return super().__new__(metacls, cls, bases, dict)
def __init__(self, cls, bases, dict):
print(f”Calling __init__ method of {super()}\n”)
super().__init__(cls, bases,dict)

def __call__(self, *args, **kwargs):
print(f”Calling __call__ method of {super()}\n”)
return super().__call__(*args, **kwargs)
class A(metaclass=ExampleMeta):
def __init__(self):
print(“This is when the new class instance gets created\n”)
print(f”Calling __init__ method of {self}”)
===============>AFTER EXECUTION OF ABOVE
Metacls: <class '__main__.ExampleMeta'>
cls: A
bases: ()
Calling __prepare__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __new__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __init__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>----------------------------------------------------------a = A()
===============>AFTER EXECUTION OF ABOVE
Calling __call__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>This is when the new class instance gets createdCalling __init__ method of <__main__.A object at 0x7f1160225d60>
5, đầu tiên là

>>> __metaclass__ = type
>>>
>>> class A:
.. pass
>>> a = A()

>>> a
<__main__.A object at 0x4f5cf3>
>>> type(a)
<class '__main__.A'>
>>> A
<class '__main__.A'>
>>> type(A)
<type 'type'>
5 sau đó là

>>> __metaclass__ = type
>>>
>>> class A:
.. pass
>>> a = A()

>>> a
<__main__.A object at 0x4f5cf3>
>>> type(a)
<class '__main__.A'>
>>> A
<class '__main__.A'>
>>> type(A)
<type 'type'>
3 ,

>>> __metaclass__ = type
>>>
>>> class A:
.. pass
>>> a = A()

>>> a
<__main__.A object at 0x4f5cf3>
>>> type(a)
<class '__main__.A'>
>>> A
<class '__main__.A'>
>>> type(A)
<type 'type'>
4

Chỉ khi chúng ta tạo một thể hiện của lớp

class ExampleMeta(type): @classmethod
def __prepare__(metacls, cls, bases):
print(f”Metacls: {metacls} \n cls: {cls} \n bases: {bases}\n”)
print(f”Calling __prepare__ method of {super()}\n”)
return super().__prepare__(cls, bases)
def __new__(metacls, cls, bases, dict):
print(f”Calling __new__ method of {super()}\n”)
return super().__new__(metacls, cls, bases, dict)
def __init__(self, cls, bases, dict):
print(f”Calling __init__ method of {super()}\n”)
super().__init__(cls, bases,dict)

def __call__(self, *args, **kwargs):
print(f”Calling __call__ method of {super()}\n”)
return super().__call__(*args, **kwargs)
class A(metaclass=ExampleMeta):
def __init__(self):
print(“This is when the new class instance gets created\n”)
print(f”Calling __init__ method of {self}”)
===============>AFTER EXECUTION OF ABOVE
Metacls: <class '__main__.ExampleMeta'>
cls: A
bases: ()
Calling __prepare__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __new__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __init__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>----------------------------------------------------------a = A()
===============>AFTER EXECUTION OF ABOVE
Calling __call__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>This is when the new class instance gets createdCalling __init__ method of <__main__.A object at 0x7f1160225d60>
5 , cụ thể là,
         metaclass                  metaclass
^ ^
| |
instance instance
| |
class B ---inheritance--> class A
^ ^
| |
instance instance
| |
b a
0 , thì phương thức
class ExampleMeta(type): @classmethod
def __prepare__(metacls, cls, bases):
print(f”Metacls: {metacls} \n cls: {cls} \n bases: {bases}\n”)
print(f”Calling __prepare__ method of {super()}\n”)
return super().__prepare__(cls, bases)
def __new__(metacls, cls, bases, dict):
print(f”Calling __new__ method of {super()}\n”)
return super().__new__(metacls, cls, bases, dict)
def __init__(self, cls, bases, dict):
print(f”Calling __init__ method of {super()}\n”)
super().__init__(cls, bases,dict)

def __call__(self, *args, **kwargs):
print(f”Calling __call__ method of {super()}\n”)
return super().__call__(*args, **kwargs)
class A(metaclass=ExampleMeta):
def __init__(self):
print(“This is when the new class instance gets created\n”)
print(f”Calling __init__ method of {self}”)
===============>AFTER EXECUTION OF ABOVE
Metacls: <class '__main__.ExampleMeta'>
cls: A
bases: ()
Calling __prepare__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __new__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __init__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>----------------------------------------------------------a = A()
===============>AFTER EXECUTION OF ABOVE
Calling __call__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>This is when the new class instance gets createdCalling __init__ method of <__main__.A object at 0x7f1160225d60>
0 mới được gọi và do đó gọi ____12_______4 và ____12_______3 trên ____21_______5 nếu được xác định (trong trường hợp của chúng tôi chỉ ____12_______4 được xác định)

Siêu lớp so với. Di sản

Bây giờ bạn có thể thắc mắc, tại sao chúng ta lại cần một Siêu lớp nếu chúng ta có quyền thừa kế. Để trả lời rằng chúng ta cần so sánh hai

         metaclass                  metaclass
^ ^
| |
instance instance
| |
class B ---inheritance--> class A
^ ^
| |
instance instance
| |
b a

Bạn có thể thấy rằng một siêu dữ liệu được sử dụng để tạo lớp, vì vậy nó thường được sử dụng làm nhà máy sản xuất lớp. Khi bạn tạo một đối tượng bằng cách gọi lớp, Python sẽ tạo một lớp mới bằng cách gọi siêu dữ liệu thông qua các phương thức_______12_______4 và


>>> __metaclass__ = type
>>>
>>> class A:
.. pass
>>> a = A()

>>> a
<__main__.A object at 0x4f5cf3>
>>> type(a)
<class '__main__.A'>
>>> A
<class '__main__.A'>
>>> type(A)
<type 'type'>
3, đồng thời bạn có thể sửa đổi việc tạo thể hiện của lớp bằng cách sử dụng
class ExampleMeta(type): @classmethod
def __prepare__(metacls, cls, bases):
print(f”Metacls: {metacls} \n cls: {cls} \n bases: {bases}\n”)
print(f”Calling __prepare__ method of {super()}\n”)
return super().__prepare__(cls, bases)
def __new__(metacls, cls, bases, dict):
print(f”Calling __new__ method of {super()}\n”)
return super().__new__(metacls, cls, bases, dict)
def __init__(self, cls, bases, dict):
print(f”Calling __init__ method of {super()}\n”)
super().__init__(cls, bases,dict)

def __call__(self, *args, **kwargs):
print(f”Calling __call__ method of {super()}\n”)
return super().__call__(*args, **kwargs)
class A(metaclass=ExampleMeta):
def __init__(self):
print(“This is when the new class instance gets created\n”)
print(f”Calling __init__ method of {self}”)
===============>AFTER EXECUTION OF ABOVE
Metacls: <class '__main__.ExampleMeta'>
cls: A
bases: ()
Calling __prepare__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __new__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>Calling __init__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>----------------------------------------------------------a = A()
===============>AFTER EXECUTION OF ABOVE
Calling __call__ method of <super: <class 'ExampleMeta'>, <ExampleMeta object>>This is when the new class instance gets createdCalling __init__ method of <__main__.A object at 0x7f1160225d60>
0. Vì bạn có thể ghi đè các phương thức này trong Siêu dữ liệu tùy chỉnh và thậm chí tạo các phương thức ma thuật của riêng bạn (bất kỳ phương thức nào có
         metaclass                  metaclass
^ ^
| |
instance instance
| |
class B ---inheritance--> class A
^ ^
| |
instance instance
| |
b a
9, bạn có thể làm thêm nhiều việc khi tạo một lớp

Nhưng hãy cẩn thận với việc lạm dụng nó. Và hầu như luôn sử dụng tính kế thừa khi thực hiện OOP vì Siêu dữ liệu dành cho hoạt động bên ngoài các ràng buộc đó và hầu như không cần thiết ngoại trừ một số trường hợp sử dụng nâng cao

Ví dụ: nếu chúng ta muốn ghi đè phương thức (metaclass=ABCMeta)0 thì chúng ta không thể thực hiện điều đó thông qua kế thừa, nhưng chúng ta có thể thực hiện điều đó thông qua Metaclass. Nhưng luôn luôn sử dụng nó một cách cẩn thận

Trong Python, bạn nên biến Metaclass thành phương sách cuối cùng của mình trừ khi bạn không thể sắp xếp nó bằng tính kế thừa hoặc sử dụng mẫu trang trí

__ mới __ trả lại bằng Python là gì?

Khi tạo các đối tượng Python, phương thức __new__ là phương thức đầu tiên được gọi và chịu trách nhiệm trả về một thể hiện mới của lớp . Mặt khác, __init__ không trả lại bất cứ thứ gì. Nó chỉ chịu trách nhiệm khởi tạo thể hiện SAU KHI nó được tạo.

Thuộc tính siêu dữ liệu trong Python là gì?

Thuộc tính __metaclass__ được giới thiệu để cung cấp cho lập trình viên một số quyền kiểm soát ngữ nghĩa của câu lệnh lớp . Đặc biệt, nó giúp dễ dàng chuyển đổi từ các lớp kiểu cũ (không được trình bày trong hướng dẫn này) và các lớp kiểu mới (được gọi đơn giản là các lớp trong hướng dẫn này).

Khi nào nên sử dụng siêu dữ liệu Python?

Sau khi xem xét các trường hợp sử dụng cụ thể và phổ biến nhất, trường hợp duy nhất mà bạn hoàn toàn PHẢI sử dụng siêu dữ liệu là khi bạn muốn sửa đổi tên lớp hoặc danh sách các lớp cơ sở . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . , because once defined, these parameters are baked into the class, and no decorator or function can unbake them.

Sự khác biệt giữa __ new __ và __ init __ trong Python là gì?

Hàm khởi tạo trong python được gọi là __new__ và __init__ là hàm khởi tạo. Trích dẫn tài liệu về python, __new__ được sử dụng khi bạn cần kiểm soát việc tạo phiên bản mới trong khi __init__ được sử dụng khi bạn cần kiểm soát việc khởi tạo phiên bản mới.