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

python的__call__、__str__、__repr__、__init__、__class__、__name___、__all__、__doc__、__del__等魔术方法的作用的更多相关文章

  1. 复习python的__call__ __str__ __repr__ __getattr__函数 整理

    class Www: def __init__(self,name): self.name=name def __str__(self): return '名称 %s'%self.name #__re ...

  2. python基础---- __getattribute__----__str__,__repr__,__format__----__doc__----__module__和__class__

    目录: 一. __getattribute__ 二.__str__,__repr__,__format__ 三.__doc__ 四.__module__和__class__ 一. __getattri ...

  3. Python的程序结构[1] -> 方法/Method[4] -> 魔术方法 __call__ / __str__ / __repr__

    __call__ 方法 __call__ 是当对象被调用时会调用的方法,允许一个对象(类的实例等)像函数一样被调用,也可以传入参数. 1 class Foo(): 2 def __init__(sel ...

  4. Python——详解__str__, __repr__和__format__

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是Python专题的第10篇文章,我们来聊聊Python当中的类. 打印实例 我们先从类和对象当中最简单的打印输出开始讲起,打印一个实例 ...

  5. __call__ 和 __str__ 魔术方法

    魔术方法,在python中,是通过触发的形式调用,之所以称为魔术方法,是因为不需要特地的打印或调用它,在某些特定的时候,他会自己调用,所谓的特定的时候,也是我们自己所输入的代码操作的,不是莫名其妙的触 ...

  6. Python的魔术方法详解

    构造和初始化 __init__我们很熟悉了,它在对象初始化的时候调用,我们一般将它理解为"构造函数". 实际上, 当我们调用x = SomeClass()的时候调用,__init_ ...

  7. Python中的常用魔术方法介绍

    1.__init__ 初始化魔术方法 触发时机:初始化对象时触发(不是实例化触发,但是和实例化在一个操作中) 参数:至少有一个self,接收对象 返回值:无 作用:初始化对象的成员 注意:使用该方式初 ...

  8. Python最会变魔术的魔术方法,我觉得是它!

    在上篇文章中,我有一个核心的发现:Python 内置类型的特殊方法(含魔术方法与其它方法)由 C 语言独立实现,在 Python 层面不存在调用关系. 但是,文中也提到了一个例外:一个非常神秘的魔术方 ...

  9. python面对对象编程------4:类基本的特殊方法__str__,__repr__,__hash__,__new__,__bool__,6大比较方法

    一:string相关:__str__(),__repr__(),__format__() str方法更面向人类阅读,print()使用的就是str repr方法更面对python,目标是希望生成一个放 ...

随机推荐

  1. 移动平台自动化测试:appium(二)

    环境搭建.本环境基于win7_x64搭建 安装环境需要用到的工具清单: android sdk:https://developer.android.com/studio/index.html Appi ...

  2. 不允许有匹配 "[xX][mM][lL]" 的处理指令目标。

    xml文件报错: 不允许有匹配 "[xX][mM][lL]" 的处理指令目标. 指的注意的是规范的XML格式:  <?xml version="1.0" ...

  3. LeetCode -- Longest Increasing Subsequence(LIS)

    Question: Given an unsorted array of integers, find the length of longest increasing subsequence. Fo ...

  4. 一文看懂Kafka消息格式的演变

    摘要 对于一个成熟的消息中间件而言,消息格式不仅关系到功能维度的扩展,还牵涉到性能维度的优化.随着Kafka的迅猛发展,其消息格式也在不断的升级改进,从0.8.x版本开始到现在的1.1.x版本,Kaf ...

  5. The Cave

    The Cave 题目描述 给定一棵有n个节点的树,相邻两点之间的距离为1. 请找到一个点x,使其满足所有m条限制,其中第i条限制为dist(x,a[i])+dist(x,b[i])<=d[i] ...

  6. php56升级后php7 mcrypt_encrypt 报错

    mcrypt_encrypt(MCRYPT_BLOWFISH, $passphrase, $data, MCRYPT_MODE_CBC, $iv); openssl_encrypt($data, &q ...

  7. python带header

    headers = { "Accept":"text/html,application/xhtml+xml,application/xml;", "A ...

  8. 模拟Windows系统“回收站”

    HTML: <!DOCTYPE html><html> <head> <meta http-equiv="content-type" co ...

  9. NIO的介绍及使用(总结)

    传统的socket IO中,需要为每个连接创建一个线程,当并发的连接数量非常巨大时,线程所占用的栈内存和CPU线程切换的开销将非常巨大.使用NIO,不再需要为每个线程创建单独的线程,可以用一个含有限数 ...

  10. Topcoder SRM 600 div1题解

    日常TC计划正式启动! Easy(250pts): 题目大意:给你一个集合,里面一堆数,初始数为0,给你一个目标数,你可以选择集合中若干个数进行OR操作来得到目标数.问至少删去多少个数,使得你永远无法 ...