9.3 day29

メタクラスとは何ですか

Pythonでは、すべてのものがオブジェクトのクラスそして確かに、オブジェクトであります

クラスがオブジェクトであれば、彼はメタクラスと呼ばれ、このクラスのインスタンスによって取得する必要があります。その生成されたクラスのクラス、メタクラスと呼ばれます

class Person:
    def __init__(self,name):
        self.name=name
    def score(self):
        print('分数是100')

p=Person('nick')

# a=Person
# p1=a('nick')
# print(p1.name)

#如何找元类?
# print(type(p))
#同理:type类是产生所有类的元类
# print(type(Person))
print(type(dict))
print(type(list))
print(type(str))
print(type(object))

print(type(type))

上述の構造は、<クラス「タイプ」>である、すなわち、一般的には、メタクラス型。ビルトインタイプでメタクラスは、すべてのクラスは、タイプのインスタンス化で得られます

クラス分析の基礎となる原則

クラス+クラス名、クラスが構築されます、しかし、それは実際に製造されたメタクラスはオブジェクトのクラスをインスタンス化します。

我々はまた、直接クラスの代わりに、classキーワードを作り出す入力することができます

タイプ()__init__クラスとメソッドアウト
タイプ(object_or_name、塩基、辞書)
object_or_name:クラス名の文字列
拠点:その親クラスのすべての、基底クラス
のdict:名前空間

その後、我々は、単純なPersonクラスを定義することができます

def __init__(self,name):
    self.name=name
Person=type('Person',(object,),{'school':'oldboy','__init__':__init__})

我々はまた、入力の最後の辞書のexec()メソッドを用いて達成することができます

l={}
exec('''
school='school'
def __init__(self,name):
    self.name=name
def score(self):
    print('分数是100')
''',{},l)
Person=type('Person',(object,),l)

クラスのメタクラスを発生させることによって制御さ

カスタムメタクラスは、クラスの生産を制御するために、あなたはクラス名を制御することができ、あなたは親クラスを継承制御することができ、カスタムメタクラスコントロールクラスの名前空間は、型を継承しなければならないし、その後、カスタムクラスで、このカスタムクラスをクラスを生成しますコールメタクラス

class Mymeta(type):
    # def __init__(self,*args,**kwargs):
    def __init__(self,name,bases,dic):
        # self 就是Person类
        # print(name)
        # print(bases)
        # print(dic)
        #练习一:加限制 控制类名必须以sb开头
        if not name.startswith('sb'):
            raise Exception('类名没有以sb开头')
class sb_Person(object,metaclass=Mymeta):

    school='雄英高中'
    def __init__(self,name):
        self.name=name
    def score(self):
        print('分数是100')

上記のコードは、クラス名がSBで始まらない場合には、異常な「クラス名はSBで開始されていない」スローされます

同様に、我々はまた、間に合わなければなりませんクラスにコメントを追加することができます

コメントのクラス名.__ドキュメントを照会する**方法__ **

class Mymeta(type):
    def __init__(self,name,bases,dic):
        print(self.__dict__['__doc__'])
        doc=self.__dict__['__doc__']
        if not doc:
            # 没有加注释
            raise Exception('你的类没有加注释')
#metaclass=Mymeta  指定这个类生成的时候,用自己写的Mymeta这个元类
class Person(object,metaclass=Mymeta):
    '''
    注释
    '''
    school='音乃木坂学院'
    def __init__(self,name):
        self.name=name
    def score(self):
        print('分数是100')

コールプロセス制御クラス

コールプロセス制御クラスは、実際の制御対象で生産されます

私たちは、オブジェクトプラス()場合、それはクラスのメソッドを呼び出します、__call__時間を使用__call__

だから私たちは、クラスの追加を(使用する場合)する場合、それ?もちろん、私たちは__call__の元クラスのメソッドを呼び出します。

したがって、我々は、プロパティを隠すには、クラスの元に、クラスで唯一のクラスは、物事を変更することはできません

class Mymeta(type):
    def __call__(self, *args, **kwargs):
        obj=object.__new__(self)
        # self.__init__(obj,*args, **kwargs)    # 也可以用
        obj.__init__(*args, **kwargs)
        # print(obj.__dict__)
        obj.__dict__={ '_%s__%s'%(self.__name__,k):v for k,v in obj.__dict__.items()}
        # print(obj.__dict__)
        return obj

class Person(object, metaclass=Mymeta):
    school = 'oldboy'
    def __init__(self, name):
        self.name = name
    def score(self):
        print('分数是100')
p = Person(name='nick')
print(p.__dict__)
# print(p.name) # 会报错,因为已经被隐藏

プロパティは、メタクラス検索順序を持っていた後、

Propertyクラスの検索順序:--->エラーに--->種類の独自の定義を見つけるために、親クラスに---> MROの継承を探す---->元のクラスを見つけるために、クラス自体で始まる
オブジェクト不動産検索順序は:> --- --->エラーを見つけるための親クラスへ---> MROの継承を見つけるためのクラスを見つけるために、オブジェクト自身で始まります

class Mymeta(type):
    n=444

    def __call__(self, *args, **kwargs): #self=<class '__main__.OldboyTeacher'>
        obj=self.__new__(self)
        # print(self.__new__ is object.__new__) #True
        obj.__init__(*args, **kwargs)
        return obj


class Bar(object):
    # n=333
    pass

    # def __new__(cls, *args, **kwargs):
    #     print('Bar.__new__')

class Foo(Bar):
    # n=222
    pass

    # def __new__(cls, *args, **kwargs):
    #     print('Foo.__new__')

class OldboyTeacher(Foo,metaclass=Mymeta):
    # n=111

    school='oldboy'

    def __init__(self,name,age):
        self.name=name
        self.age=age

    def say(self):
        print('%s says welcome to the oldboy to learn Python' %self.name)

おすすめ

転載: www.cnblogs.com/hyc123/p/11454384.html