1. 程式人生 > >python3__面向物件__類的起源(type)

python3__面向物件__類的起源(type)

1.一切皆物件

python中有一個重要的概念那就是一切皆物件;一切都可以賦值給變數(引用)

①內建型別賦值

②將類型別賦值給變數

③將函式賦值給變數

④將自定義類賦值給變數

class Foo(object):
    def __init__(self, name):
        self.name = name


if "__main__" == __name__:

    a = 1
    print(type(a))  # <class 'int'>
    a = "123"
    print(type(a))  # <class 'str'>
    a = int
    str = "123"
    print(type(str), type(a(str)))  # <class 'str'> <class 'int'>
    a = Foo
    f = a("maxin")
    print(f.name)  # maxin

2.類的起源

在1中可知,python中一切皆物件,那麼f是由Foo類例項化所得,那Foo這個物件是由那個類例項化所得的那?Type

類名 = type("類名", (當前類的基類, ), 類成員字典)

那問題來了?type類中是如何建立類的?恰巧__metaclass__表示的是該類由誰來例項化建立,因此可藉助於type類的派生類來檢視類的建立過程。

 

class MyType(type):
    def __init__(self, what, bases=None, dict=None):
        print("MyType __init__")
        super(MyType, self).__init__(what, bases, dict)

    def __call__(self, *args, **kwargs):
        print("MyType __call__")
        obj = self.__new__(self, *args, **kwargs)
        self.__init__(obj, *args, **kwargs)



class Foo(object):
    # __metaclass__: 表示該類是由誰來例項化建立的
    __metaclass__ = MyType

    def __init__(self, name):
        self.name = name
        print("Foo __init__")

    def __new__(cls, *args, **kwargs):
        print("Foo __new__")
        return object.__new__(cls)


if "__main__" == __name__:

    obj = Foo("maxin")
    print(obj.name)
    print(Foo.__metaclass__)  # <class '__main__.MyType'>
    # python3
    # Foo __new__ / Foo __init__ / maxin
    # python2
    # MyType __init__ / MyType __call__ / Foo __new__ / Foo __init__