• 类的特殊成员方法


    类的特殊成员方法

    1、__doc__  表示类的描述信息

    class Dog(object):
        '''这个是描述狗的一个类'''
        def __init__(self,name):
            self.name = name
            self.__weight = 100
    
        def sayhi(self):
            print('my wigth is ', self.__weight,)
    
    d = Dog('二哈')
    print(d.__doc__)  #这个是描述狗的一个类
    print(Dog.__doc__) #这个是描述狗的一个类
    

     2、__module__ 和 __class__

    __module__ 表示当前操作的对象在哪个模块

    __class__ 表示当前操作的对象是哪个类

    3、__init__ 构造方法,类在实例化创建对象时,自动触发的方法

    4、__del__ 析构方法  当对象在内存被释放时,自动触发执行。

    5、__call__ 对象后面加括号,触发执行

    class Dog(object):
        '''这个是描述狗的一个类'''
        def __init__(self,name):
            self.name = name
            self.__weight = 100
    
        def sayhi(self):
            print('my wigth is ', self.__weight,)
        def __call__(self, *args, **kwargs):
            print('runing call',args,kwargs)
    d = Dog('二哈')
    Dog('二哈')() #runing call () {}
    d(1,2,3,4,5,name=888) #runing call (1, 2, 3, 4, 5) {'name': 888}

     6、__dict__ 查看类或者对象中的所有成员

    class Dog(object):
        '''这个是描述狗的一个类'''
        def __init__(self,name):
            self.name = name
            self.__weight = 100
    
        def sayhi(self):
            print('my wigth is ', self.__weight,)
        def __call__(self, *args, **kwargs):
            print('runing call',args,kwargs)
    d = Dog('二哈')
    print(Dog.__dict__) 
    #{'__dict__': <attribute '__dict__' of 'Dog' objects>, '__doc__': '这个是描述狗的一个类', '__init__': <function Dog.__init__ at 0x00000000010501E0>, 
    #'__call__': <function Dog.__call__ at 0x00000000010502F0>, 'sayhi': <function Dog.sayhi at 0x0000000001050268>, '__module__': '__main__',
    #'__weakref__': <attribute '__weakref__' of 'Dog' objects>} #打印类里面的所有属性,不包括实例。 print(d.__dict__) #{'_Dog__weight': 100, 'name': '二哈'} 打印所有实例的属性,不包括类。

     7、__str__ 如果一个类定义了__str__方法 ,那么在打印对象时。默认输出该方法的返回值

    class Dog(object):
        '''这个是描述狗的一个类'''
        def __init__(self,name):
            self.name = name
            self.__weight = 100
    
        def sayhi(self):
            print('my wigth is ', self.__weight,)
        def __call__(self, *args, **kwargs):
            print('runing call',args,kwargs)
        def __str__(self):
            return "obj:%s" % self.name
    d = Dog('二哈')
    d1 = Dog('秋田')
    print(d) # obj:二哈
    print(d1) # obj:秋田
    

     8、__getitem__、__setitem__、__delitem__

    用于索引操作,比如字典、以上表示获取、设置、删除数据。

    class Foo(object):
        def __getitem__(self, key):
            print('__getitem__',key)
    
        def __setitem__(self, key, value):
            print('__setitem__',key,value)
    
        def __delitem__(self, key):
            print('__delitem__',key)
    
    obj = Foo()
    result = obj['k1']   # __getitem__ k1
    obj['k2'] = 'alex'  # __setitem__ k2 alex
    del obj['k1']   #  __delitem__ k1
    

     9、__new__ __metaclass__

    一切事物皆对象。

    class Foo(object):
        def __init__(self,name):
            self.name = name
    
    f = Foo('alex') 
    print(type(f)) #<class '__main__.Foo'>
    print(type(Foo)) #<class 'type'>
    

     可以看到f是实例化Foo后的一个对象,不仅f是一个对象,Foo类本身也是一个对象。

    f对象是Foo的一个实例,Foo类是type类的一个实例。说明Foo类是通过type类的构造方法创建。

    那么,创建类就可以有两种方式:

    1、普通方式

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

    2、特殊方式

    def func(self):
        print('hello world')
    
    Foo = type('Foo',(),{'func':func}) #Foo表示要实例化之后的类,()表示要继承的类,func表示类里面的方法
    
    print(type(Foo))
    f= Foo() #<class 'type'>
    f.func() #hello world
    

     

    既然可以通过这种方式创建类,并且可以添加类的方法,也可以把__init__这种方法装载进去。

    def func(self):
        print('hello world')
    
    def __init__(self,name,age):
        self.name = name
        self.age = age
    
    Foo = type('Foo',(),{'func':func,'__init__':__init__}) #Foo表示要实例化之后的类,()表示要继承的类,func表示类里面的方法
     
    f= Foo() #TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'
    

     这里提示实例化的时候__init__里面要传入两个参数。

    def func(self):
        print('hello world')
    
    def __init__(self,name,age):
        self.name = name
        self.age = age
    
    Foo = type('Foo',(),{'func':func,'__init__':__init__}) #Foo表示要实例化之后的类,()表示要继承的类,func表示类里面的方法
    
    f= Foo('alex','age')
    print(f.name,f.age) #alex age
    

     那么,类默认是通过type类实例化产生,type类如何创建类?类又是如何创建对象的?

    其实类中有一个属性 __metaclass__,其用来表示该类由谁来实例化创建的。所以可以为__metaclass__设置一个type类的派生类,从而查看类创建的过程。

     1 class MyType(type):
     2     def __init__(self,*args,**kwargs):
     3 
     4         print("Mytype __init__",*args,**kwargs)
     5 
     6     def __call__(self, *args, **kwargs):
     7         print("Mytype __call__", *args, **kwargs)
     8         obj = self.__new__(self)
     9         print("obj ",obj,*args, **kwargs)
    10         print(self)
    11         self.__init__(obj,*args, **kwargs)
    12         return obj
    13 
    14     def __new__(cls, *args, **kwargs):
    15         print("Mytype __new__",*args,**kwargs)
    16         return type.__new__(cls, *args, **kwargs)
    17 
    18 print('here...')
    19 class Foo(object,metaclass=MyType):
    20 
    21 
    22     def __init__(self,name):
    23         self.name = name
    24 
    25         print("Foo __init__")
    26 
    27     def __new__(cls, *args, **kwargs):
    28         print("Foo __new__",cls, *args, **kwargs)
    29         return object.__new__(cls)
    30 
    31 f = Foo("Alex")
    32 print("f",f)
    33 print("fname",f.name)
    34 
    35 自定义元类
    View Code

    __new__()方法

    class Foo(object):
    
        def __init__(self,name):
            self.name = name
    
            print("Foo __init__")
    
        def __new__(cls, *args, **kwargs):
            print("Foo __new__",cls, *args, **kwargs)
            return object.__new__(cls)
    
    f = Foo("Alex") 
    #=========执行结果============
    Foo __new__ <class '__main__.Foo'> Alex
    Foo __init__
    

     实例化Foo类的时候会执行__init__,也会执行__new__。并且__new__会在__init__之前执行。

    有一点不明白的是__new__()方法里面的return object.__new__(cls) 做什么用的?

    尝试去掉这个return:

    class Foo(object):
    
        def __init__(self,name):
            self.name = name
    
            print("Foo __init__")
    
        def __new__(cls, *args, **kwargs):
            print("Foo __new__",cls, *args, **kwargs)
    
    
    f = Foo("Alex")
    #=============执行结果============
    Foo __new__ <class '__main__.Foo'> Alex
    

     可以看到只执行了__new__()方法,并没有执行__init__这个方法。说明这个实例并没有真正被创建。

    print(f.name) #AttributeError: 'NoneType' object has no attribute 'name'
    

    说明__new__()用来创建实例的,object.__new__用父类的方法创建实例,那么传过去的cls做什么的?

    cls 相当于self,也就是Foo,因为Foo也是一个对象,你要继承父类的东西就要把自己传过去。

    print(object.__new__(cls)) #<__main__.Foo object at 0x0000000000A52320> #Foo内存对象
    

    __metaclass__

     

     1 class MyType(type):
     2     def __init__(self,*args,**kwargs):
     3 
     4         print("Mytype __init__",*args,**kwargs)
     5         super(MyType, self).__init__( *args,**kwargs)
     6 
     7     def __call__(self, *args, **kwargs):
     8         print("Mytype __call__", *args, **kwargs)
     9         #obj = self.__new__(self)
    10         #self.__init__(obj,*args, **kwargs)
    11 
    12 class Foo(object):
    13     __metaclass__ = MyType
    14     def __init__(self,name):
    15         self.name = name
    16 
    17         print("Foo __init__")
    18 
    19     def __new__(cls, *args, **kwargs):
    20         print("Foo __new__",cls, *args, **kwargs)
    21         return object.__new__(cls)
    22 
    23 f = Foo("Alex")
    View Code

     类的生成 调用 顺序依次是 __new__ --> __init__ --> __call__

     metaclass 详解文章:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python 得票最高那个答案写的非常好

  • 相关阅读:
    Codeforces Round #535 (Div. 3) 1108C
    Codeforces Round #536 (Div. 2) B. Lunar New Year and Food Ordering
    Leetcode--136. Single Number(easy)
    Leetcode--572. Subtree of Another Tree(easy)
    Leetcode--101. Symmetric Tree(easy)
    Leetcode--680. Valid Palindrome II(easy)
    2017百度之星资格赛 1003 度度熊与邪恶大魔王 背包DP
    台州 OJ 1704 Cheapest Palindrome 回文 区间DP
    洛谷 P1019 单词接龙 深搜
    UVA 11882 Biggest Number 深搜 剪枝
  • 原文地址:https://www.cnblogs.com/qing-chen/p/7436891.html
Copyright © 2020-2023  润新知