zoukankan      html  css  js  c++  java
  • python的__call__、__str__、__repr__、__init__、__class__、__name___、__all__、__doc__、__del__等魔术方法的作用

    python中,一切都是对象

    在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”--魔术方法

    1、__call__:作用是把类实例变成一个可调用对象

    在Python中,函数其实是一个对象:
    
    >>> f = abs
    >>> f.__name__
    'abs'
    >>> f(-123)
    123
    由于 f 可以被调用,所以,f 被称为可调用对象。
    
    所有的函数都是可调用对象。
    所有的函数都默认实现了方法"__call__",所以所有的函数的都是可以被调用的
    >>> def f():
    ...  print 2
    ...
    >>> f.__name__
    'f'
    >>> f.__call__
    <method-wrapper '__call__' of function object at 0x10d0ec230>
    >>> 一个类实例也可以变成一个可调用对象,只需要实现一个特殊方法__call__()。 我们把 Person 类变成一个可调用对象: class Person(object): def __init__(self, name, gender): self.name = name self.gender = gender def __call__(self, friend): print 'My name is %s...' % self.name print 'My friend is %s...' % friend 现在可以对 Person 实例直接调用: >>> p = Person('Bob', 'male') >>> p('Tim') My name is Bob... My friend is Tim... 单看 p('Tim') 你无法确定 p 是一个函数还是一个类实例,所以,在Python中,函数也是对象,对象和函数的区别并不显著。

    但是如果,你这样定义类,不实现__call__():
    class Person(object):
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
    
    

     >>> p=Person('Bob','male')
     >>> p
     <__main__.Person object at 0x1081a5e90>
     >>> p('Tim')
       Traceback (most recent call last):
         File "<stdin>", line 1, in <module>
       TypeError: 'Person' object is not callable

    2、__str__:作用是把一个类的实例变成 str,打印显示

        __repr__:作用是调用对象的返回值,

    举例见差别:

    未定义__str__()函数的情况
    >>> class Person(object): ... def __init__(self, name, gender): ... self.name = name ... self.gender = gender ... >>> p=Person('Bob','male') >>> p <__main__.Person object at 0x108210490> >>> print p <__main__.Person object at 0x108210490>

    定义__str__()函数,但是未定义__repr__()的情况:
    >>> class Person(object): ... def __init__(self, name, gender): ... self.name = name ... self.gender = gender ... def __str__(self): ... return '(Person: %s, %s)' % (self.name, self.gender) ... >>> p = Person('Bob','male') >>> p <__main__.Person object at 0x1081a5e90> >>> print p (Person: Bob, male)
    同时定义__str__和__repr__的情况:
    >>> class Person(object): ... def __init__(self, name, gender): ... self.name = name ... self.gender = gender ... def __str__(self): ... return '(Person: %s, %s)' % (self.name, self.gender) ... __repr__=__str__ ... >>> p = Person('Bob','male') >>> p (Person: Bob, male) >>> print p (Person: Bob, male) >>>
    分别定义__str__和__repr__的情况:
    >>> class Person(object):
    ...     def __init__(self, name, gender):
    ...         self.name = name
    ...         self.gender = gender
    ...     def __str__(self):
    ...         return '(Person: %s, %s)' % (self.name, self.gender)
    ...     def __repr__(self):
    ...        return 'xxxx'
    ...
    >>> p=Person('Bob','male')
    >>> p
    xxxx
    >>> print p
    (Person: Bob, male)
    >>>

     3、__init__:作用是class的初始化函数,类似于Java/C++里的构造函数

     4、__class__:作用,class的实例直接调用就表示生成实例的类

    >>> class A:
    ...     def __init__(self,url):
    ...         self.url = url
    ...     def out(self):
    ...         return self.url
    ...
    >>>
    >>> a = A('news.163.com')
    >>> print a.out()
    news.163.com
    >>>
    >>> b = a.__class__('www.bccn.net')
    >>> print b.out()
    www.bccn.net
    >>>
    >>>
    >>> print A
    __main__.A
    >>> print a.__class__
    __main__.A
    >>>

    还有一种用法:
    >>> def foo():
    ...  pass
    ...
    >>> foo.__class__
    <type 'function'>
    >>> foo.__name__
    'foo'
    >>>

     5、__name__:表示函数的名字

    >>> def a():
    ...   print 2
    ...
    >>> f=a
    >>> f.__name__
    'a'
    >>> f
    <function a at 0x103996320>
    >>> f()
    2
    >>> f=a()
    2
    >>> f
    >>> f.__name__
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'NoneType' object has no attribute '__name__'
    >>>

     6、__slots__:用来限制class的实例动态添加属性: https://eastlakeside.gitbooks.io/interpy-zh/content/slots_magic/

    由于Python是动态语言,任何实例在运行期都可以动态地添加属性。
    
    如果要限制添加的属性,例如,Student类只允许添加 name、gender和score 这3个属性,就可以利用Python的一个特殊的__slots__来实现。
    
    顾名思义,__slots__是指一个类允许的属性列表class Student(object):
        __slots__ = ('name', 'gender', 'score')
        def __init__(self, name, gender, score):
            self.name = name
            self.gender = gender
            self.score = score
    现在,对实例进行操作:
    
    >>> s = Student('Bob', 'male', 59)
    >>> s.name = 'Tim' # OK
    >>> s.score = 99 # OK
    >>> s.grade = 'A'
    Traceback (most recent call last):
      ...
    AttributeError: 'Student' object has no attribute 'grade'
    __slots__的目的是限制当前类所能拥有的属性,如果不需要添加任意动态的属性,使用__slots__也能节省内存
    可以使用工具ipython_memory_usage验证__slots__在节省内存上的作用,这个工具可以计算出每一条命令行使用的内存大小。安装这个工具的时候,mac下建议使用virtualenv环境,减免冲突问题: https://github.com/ianozsvald/ipython_memory_usage
    class Person(object):
    
        __slots__ = ('name', 'gender')
    
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
    
    class Student(Person):
    
        __slots__ = ('score',)
    
        def __init__(self,name,gender,score):
            super(Student,self).__init__(name,gender)
            self.score=score
    
    s = Student('Bob', 'male', 59)
    s.name = 'Tim'
    s.score = 99
    print s.score
    复制代码

     7、__all__的作用参见http://www.cnblogs.com/shengulong/p/7425088.html,主要用例class向外暴露接口

    8、__doc__该属性用于描述该对象的作用。

    9、__del__:与__init__构造函数相反,它是一个析构函数。

      创建对象后,python解释器默认调用__init__()方法。当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法。在python中,对于开发者来说很少会直接销毁对象(如果需要,应该使用del关键字销毁)。Python的内存管理机制能够很好的胜任这份工作。也就是说,不管是手动调用del还是由python自动回收都会触发__del__方法执行。

      举例:__del__对象只要在这个对象真正被删除时才会被调用。

    import time
    class Animal(object):
        # 初始化方法
        # 创建完对象后会自动被调用
        def __init__(self, name):
            print('__init__方法被调用')
            self.__name = name 
    
        # 析构方法
        # 当对象被删除时,会自动被调用
        def __del__(self):
            print("__del__方法被调用")
            print("%s对象马上被干掉了..."%self.__name)
    
    # 创建对象
    dog = Animal("哈皮狗")
    
    # 删除对象
    del dog
    
    cat = Animal("波斯猫")
    cat2 = cat
    cat3 = cat
    print("---马上 删除cat对象")
    del cat
    print("---马上 删除cat2对象")
    del cat2
    print("---马上 删除cat3对象")
    del cat3 # 这个时候,__del__对象才会被调用

    http://python.jobbole.com/88367/

    https://pycoders-weekly-chinese.readthedocs.io/en/latest/issue6/a-guide-to-pythons-magic-methods.html

  • 相关阅读:
    Chrome快捷键
    Nginx之基本介绍(一)
    windows程序调试
    python有序字典
    value是列表的字典排序
    构造Map并对其排序
    python读取文件时遇到非法字符的处理 UnicodeDecodeError: 'gbk' codec can't decode bytes in position
    python正则表达式 分割字符串
    python3 导入模块
    python3 以utf-8编码写文件
  • 原文地址:https://www.cnblogs.com/shengulong/p/7456435.html
Copyright © 2011-2022 走看看