Hướng dẫn python dynamically create class with metaclass - python tự động tạo lớp với siêu dữ liệu

Trong Python 3 tại thời điểm Metaclass được sử dụng, nó phải sẵn sàng và nó không thể biết về các cơ sở của lớp cuối cùng (không phải là Meta) để tạo ra một metaclass tại thời điểm đó.

Nhưng thay vì làm phức tạp mọi thứ (tôi thú nhận rằng tôi không thể quấn đầu bạn về nhu cầu của bạn về một lớp meta-meta)-bạn chỉ có thể sử dụng hệ thống phân cấp lớp bình thường với việc sử dụng

In[47] :Example.A
Out[47]: 'Metaclass A processed'

In[48]: Example.B
Out[48]: 'Metaclass A processed'
6 cho các metaclass của bạn. Bạn thậm chí có thể xây dựng Metaclass cuối cùng một cách linh hoạt với một cuộc gọi đơn giản đến
In[47] :Example.A
Out[47]: 'Metaclass A processed'

In[48]: Example.B
Out[48]: 'Metaclass A processed'
7:

class A(type):
    def __new__(metacls, name, bases,attrs):
        attrs['A'] = "Metaclass A processed"
        return super().__new__(metacls, name, bases,attrs)


class B(type):
    def __new__(metacls, name, bases,attrs):
        attrs['B'] = "Metaclass A processed"
        return super().__new__(metacls, name, bases,attrs)


C = type("C", (A, B), {})

class Example(metaclass=C): pass

And:

In[47] :Example.A
Out[47]: 'Metaclass A processed'

In[48]: Example.B
Out[48]: 'Metaclass A processed'

Nếu các metaclass của bạn không được thiết kế để hợp tác ngay từ đầu, sẽ rất khó để tạo ra bất kỳ phương pháp tự động nào để kết hợp chúng - và nó có thể liên quan đến việc gắn khỉ vào

In[47] :Example.A
Out[47]: 'Metaclass A processed'

In[48]: Example.B
Out[48]: 'Metaclass A processed'
8 trong một số chất xây dựng Metaclasses.

Vì không cần phải giải thích xây dựng

In[47] :Example.A
Out[47]: 'Metaclass A processed'

In[48]: Example.B
Out[48]: 'Metaclass A processed'
9, bạn có thể sử dụng chức năng bình thường làm tham số Metaclass, sẽ kiểm tra các cơ sở và xây dựng Metaclass có nguồn gốc động:

def Auto(name, bases, attrs):
    basemetaclasses = []
    for base in bases:
        metacls = type(base)
        if isinstance(metacls, type) and metacls is not type and not metacls in basemetaclasses:
            basemetaclasses.append(metacls)
    dynamic = type(''.join(b.__name__ for b in basemetaclasses), tuple(basemetaclasses), {})
    return dynamic(name, bases, attrs)

.

Bạn có chúng để vượt qua Auto dưới dạng metaclass cho các lớp có nguồn gốc, nhưng nếu không thì nó hoạt động như trong ví dụ của bạn:

In [61]: class AA(metaclass=A):pass

In [62]: class BB(metaclass=B):pass

In [63]: class CC(AA,BB): pass
---------------------------------------------------------------------------
...
TypeError:   metaclass conflict
...

In [66]: class CC(AA,BB, metaclass=Auto): pass

In [67]: type(CC)
Out[67]: __main__.AB

In [68]: CC.A
Out[68]: 'Metaclass A processed'

Bởi Bernd Klein. Sửa đổi lần cuối: 01 tháng 2 năm 2022.Bernd Klein. Last modified: 01 Feb 2022.

Trên trang này

Đằng sau hậu trường: Mối quan hệ giữa lớp và loại

Trong chương này trong hướng dẫn của chúng tôi, chúng tôi sẽ cung cấp cho bạn cái nhìn sâu sắc hơn về phép thuật xảy ra đằng sau hậu trường, khi chúng tôi xác định một lớp hoặc tạo một thể hiện của một lớp. Bạn có thể tự hỏi mình: "Tôi có thực sự phải học các chi tiết bổ sung về lập trình hướng đối tượng trong Python không?" Rất có thể là không, hoặc bạn thuộc về một số ít người thiết kế các lớp học ở cấp độ rất tiên tiến.

Đầu tiên, chúng tôi sẽ tập trung vào mối quan hệ giữa loại và lớp. Trong khi xác định các lớp học cho đến nay, bạn có thể đã tự hỏi mình, những gì đang xảy ra "đằng sau dòng". Chúng tôi đã thấy rằng việc áp dụng "loại" cho một đối tượng trả về lớp mà đối tượng là một thể hiện của:

x = [4, 5, 9]
y = "Hello"
print(type(x), type(y))

OUTPUT:

 

Nếu bạn áp dụng loại trên tên của một lớp, bạn sẽ trả về lớp "loại".

print(type(list), type(str))

OUTPUT:

 

Điều này tương tự như áp dụng loại trên loại (x) và loại (y):

x = [4, 5, 9]
y = "Hello"
print(type(x), type(y))
print(type(type(x)), type(type(y)))

OUTPUT:

 
 

Một lớp do người dùng xác định (hoặc lớp "đối tượng") là một thể hiện của lớp "loại". Vì vậy, chúng ta có thể thấy, các lớp được tạo từ loại. Trong Python3 không có sự khác biệt giữa "lớp" và "loại". Chúng trong hầu hết các trường hợp được sử dụng làm từ đồng nghĩa.

Thực tế là các lớp là các trường hợp của một lớp "loại" cho phép chúng tôi lập trình các metaclasses. Chúng ta có thể tạo các lớp, kế thừa từ lớp "loại". Vì vậy, một metaclass là một lớp con của lớp "loại".

Thay vì chỉ một đối số, loại có thể được gọi với ba tham số:

Loại (ClassName, SuperClasses, Aperty_Dict)

Nếu loại được gọi với ba đối số, nó sẽ trả về một đối tượng loại mới. Điều này cung cấp cho chúng tôi một hình thức năng động của câu lệnh lớp.

  • "ClassName" là một chuỗi xác định tên lớp và trở thành thuộc tính tên;
  • "Siêu lớp" là một danh sách hoặc tuple với các siêu lớp của lớp chúng tôi. Danh sách hoặc tuple này sẽ trở thành thuộc tính cơ sở;
  • Các thuộc tính_DICT là một từ điển, hoạt động như không gian tên của lớp chúng tôi. Nó chứa các định nghĩa cho cơ thể lớp và nó trở thành thuộc tính dict.

Hướng dẫn python dynamically create class with metaclass - python tự động tạo lớp với siêu dữ liệu

Chúng ta hãy xem một định nghĩa lớp đơn giản:

In[47] :Example.A
Out[47]: 'Metaclass A processed'

In[48]: Example.B
Out[48]: 'Metaclass A processed'
0

OUTPUT:

Chúng tôi cũng có thể sử dụng "Loại" cho xác định lớp trước đó:

In[47] :Example.A
Out[47]: 'Metaclass A processed'

In[48]: Example.B
Out[48]: 'Metaclass A processed'
1

OUTPUT:

Nói chung, điều này có nghĩa là, chúng ta có thể định nghĩa một lớp A với

In[47] :Example.A
Out[47]: 'Metaclass A processed'

In[48]: Example.B
Out[48]: 'Metaclass A processed'
2

Khi chúng ta gọi "Loại", phương thức cuộc gọi của loại được gọi. Phương thức cuộc gọi chạy hai phương thức khác: mới và init:

In[47] :Example.A
Out[47]: 'Metaclass A processed'

In[48]: Example.B
Out[48]: 'Metaclass A processed'
3

Phương thức mới tạo và trả về đối tượng lớp mới và sau đó, phương thức INIT khởi tạo đối tượng mới được tạo.

In[47] :Example.A
Out[47]: 'Metaclass A processed'

In[48]: Example.B
Out[48]: 'Metaclass A processed'
4

OUTPUT:

In[47] :Example.A
Out[47]: 'Metaclass A processed'

In[48]: Example.B
Out[48]: 'Metaclass A processed'
5

Các định nghĩa lớp cho robot và robot2 hoàn toàn khác nhau về mặt cú pháp, nhưng chúng thực hiện một cách logic cùng một lớp.

Python thực sự làm gì trong ví dụ đầu tiên, tức là "cách thông thường" của việc xác định các lớp, là như sau: Python xử lý câu lệnh lớp hoàn chỉnh từ robot lớp để thu thập các phương thức và thuộc tính của robot để thêm chúng vào các thuộc tính của loại cuộc gọi loại . Vì vậy, Python sẽ gọi loại theo cách tương tự hoặc giống như chúng ta đã làm trong Robot2.

Đào tạo Python sống

Hướng dẫn python dynamically create class with metaclass - python tự động tạo lớp với siêu dữ liệu

Các khóa học trực tuyến sắp tới

Ghi danh ở đây