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. luajit的字节码

    http://blog.csdn.net/zzz3265/article/details/41146569 这里写出了luajit的字节码

  2. 【bzoj3585/bzoj3339】mex/Rmq Problem 莫队算法+分块

    原文地址:http://www.cnblogs.com/GXZlegend/p/6805283.html 题目描述 有一个长度为n的数组{a1,a2,...,an}.m次询问,每次询问一个区间内最小没 ...

  3. 【bzoj2969】矩形粉刷 期望

    题目描述 为了庆祝新的一年到来,小M决定要粉刷一个大木板.大木板实际上是一个W*H的方阵.小M得到了一个神奇的工具,这个工具只需要指定方阵中两个格子,就可以把这两格子为对角的,平行于木板边界的一个子矩 ...

  4. C#中不用安装Oracle客户端连接Oracle数据库(转)

    原文地址:http://www.cnblogs.com/jiangguang/archive/2013/02/19/2916882.html 0.首先,从Oracle网站上下载对应版本的Oracle ...

  5. [SDOI2015][bzoj3990] 序列 [搜索]

    题面 传送门 思路 首先,这道题目有一个非常显然(但是我不会严格证明,只能意会一下)的结论:一个合法的操作序列中,任意两个操作是可以互换的 那么,这个结论加上本题极小的数据范围,为什么不搜索一下呢? ...

  6. Eclipse EE导入maven工程

    Eclipse EE下载地址:https://eclipse.org/downloads/ 启动Eclipse后,点击File->Import,选择Existing Maven Projects ...

  7. python代理池的实现

    https://github.com/wangqifan/ProxyPool http://python.jobbole.com/86994/

  8. 使用rssh创建一个安全的文件服务器

    使用rssh创建一个安全的文件服务器 目前有这样一个需求,公司需要一台linux服务器作为文件服务器,但是基于安全性考虑,我不想使用ftp或者samba,但又必须允许用户上传文件.怎么办呢? 因为是l ...

  9. angular组件--tips提示功能

    将组件封装起来在项目中开发很实用,之前遭遇过一次痛苦的经历,那阵子改的要吐血了.常用的组件封装起来,改公共的地方,往往多处受用. 例如:我在项目中引用  tips.text('加载中...',fals ...

  10. laravel的elixir和gulp用来对前端施工

    使用laravel elixer npm install --global gulp  ok 然后在安装好的laravel 下 npm install 以安装 laravel-elixir subli ...