23個

一、元类

Pythonオブジェクトのすべては、オブジェクトは、クラスオブジェクトは、クラスがインスタンス化されることによって、インスタンス化クラスを生成することができる生成されています。そして、クラスのカテゴリはメタクラスを生成されるインスタンス化します。

class B
    def __init__(self,v)
print(type(B))

<class 'type'>

印刷を使用(タイプ(クラス))メソッドは、クラスのクラスに見出すことができます。

ビルトインタイプのメタクラスは、すべてのクラスがタイプのインスタンスによって生成され、pythonのです。

二つの、基本的な原理のクラス分析

通常、構築クラス+クラス仕方のクラス名を使用して、実際には、これらのクラスが生成され、メタクラスによってインスタンス化されています。内蔵型Pythonのメタクラスは、クラスが生成タイプ、及び渡されたパラメータの束によってインスタンス化されます。

内蔵型は、メソッドのクラスのクラス__init__生成されます。

    # 类的源码
    def __init__(cls, what, bases=None, dict=None): # known special case of type.__init__
        """
        type(object_or_name, bases, dict)
        type(object) -> the object's type
        type(name, bases, dict) -> a new type
        # (copied from class doc)
        """
        pass

object_or_name、塩基、dictのプロデュースクラスによってメタクラス(:辞書:クラス名の文字列、親クラスの名前空間)の方法は、代わりにclassキーワードの方法を使用することができます。

#通过type来直接产生类,不用class关键字了
l={}
exec('''
school='oldboy'
def __init__(self,name):
    self.name=name
def score(self):
    print('分数是100')
''',{},l)
def __init__(self,name):
    self.name=name

# Person=type('Person',(object,),{'school':'oldboy','__init__':__init__})
#
Person=type('Person',(object,),l)

第三に、制御要素クラスによって生成されました

クラス名を制御することによって、クラスがそれによってクラスの生成を制御し、名前空間のクラスのカスタムメタクラスを制御するための親クラスの制御方法から継承されました。

カスタムメタクラス、型メタクラスを継承する必要があります。

class A(type):

class B(metaclass=  A):

メタクラス=メタクラス指定されたクラスBのA.

演習:カスタム元クラス、コントロールクラスが生成され、クラスの名前空間は、成功、または失敗を作成するには、名前のフィールドを持っている必要があります。

lass Mymeta(type):
    def __init__(self,name):
        if not 'name' in name:
            raise   TypeError('没有name字段')

class Aname(object,metaclass=Mymeta):
    def __init__(self,name):
        self.name = name

第四に、メタクラスクラスの呼制御により、

クラスを呼び出すことによって、メタクラス制御は、実際の制御対象で生成されます。

class Mymeta(type):
    def __call__(self, *args, **kwargs):
        # print('xxx')

        return 1

class Person(object,metaclass=Mymeta):
    school='oldboy'
    def __init__(self,name):
        self.name=name
    def score(self):
        print('分数是100')

p=Person('nick')
print(p.name)

呼び出しプロセスは、第一級__call__元クラスをトリガし、次にクラスのinitメソッドをトリガします。

演習:、メタクラスを定義した辞書を継承するクラスを定義し、それが制御メタクラスオブジェクトを生成することにより、ポイント値や割り当て機能を有し、ATTR辞書内のすべての属性は、全体のプロパティを削除します。

class Mymeta(type):
    def __call__(self, *args, **kwargs):
        obj = self.__new__(self)
        obj.__init__(*args, **kwargs)
        dic = {}
        dict.update(obj.__dict__)
        attr = {'attr':dic}
        obj.__dict__.clear()
        obj.__dict__.update(attr)
        

class Test(dict,metaclass=Mymeta):
    def __init__(self,**kwargs):
        self.__dict__.update(kwargs)
    def __getattr__(self, item):
        return self.__dict__['attr'][item]
    def __setattr__(self, key, value):
        self.__dict__['attr'][key] = value
        t = Test(name='lqz', age=18)
print(t.__dict__)
print(t.name)
print(t.age)
t.male = 'nan'
print(t.male)
print(t.__dict__)

第五に、メタクラスのプロパティの検索順序があります

Propertyクラスの検索順序:---> --->で入力エラーの独自の定義を見つけるために、親クラスに---> MROの継承を探す---->元のクラスを見つけるために、クラス自体で始まります

> --- --->エラーを見つけるための親クラスへ---> MROの継承を見つけるためのクラスを見つけるために、オブジェクト自身で始まる:オブジェクトは、順序属性検索します

5f192fd059540a603a133d3ff0b0ca0

おすすめ

転載: www.cnblogs.com/tangceng/p/11455813.html