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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
接口12:更新视频媒体通道 功能描述:创建一个媒体通道来进行视频通话 函数原形:public static int pnas_pjsua_media_video_update(int call_id, int call_type, pj_str_t* caller_udn ,nas_remote_video_info remote_video_info, pnas_video_info_others *video_info_others) 参数说明:call_type ------ 会话媒体类型,一是用于是否需要硬编解码,二是重传功能需要 caller_udn ------- 用户的号码,用于视频学习包的发送(已废弃使用) pnas_remote_video_info是一个结构体,具体传递参数如下: Unsigned media_type ----- 媒体类型, 这里只能等于2 pj_str_t remote_ip ----- 呼叫对方的IP int local_rtp_port ----- 本地传输视频RTP流的端口 int remote_rtp_port ----- 对方接收本地视频RTP流到的端口 int remote_rtcp_port ----- 对方接收本地视频RTCP流到的端口 pjmedia_dir locat_audio_dir --- { 值为0,待用; 值为1,只编码,会话只发送视频; 值为2,只解码,会话只接收视频; 值为3,编解码,会话支持同时编码和解码视频; } PNAS_VIDEO_CODEC_NAME vid_codec_name --- 编解码器(比如H264) PNAS_VIDEO_FPS fps ----- 视频帧率 PNAS_VIDEO_SIZE video_size ----- 视频分辨率 video_info_others是一个结构体,具体传递参数如下: int cap_dev --- 用于切换哪一个摄像头,是使用后置、前置还是外置摄像头 返回值:底层返回的值 PJ_ERRNO_PARAM_INVALID=170009 ----- 传入的参数为空或参数不符合要求, 比如媒体类型为音频、没有值或为空 PJ_ERRNO_POOL_ERROR=170014 ----- 创建内存池失败 PJ_ERRNO_AUDIO_STREAM_UPDATE=170015 --- 更新视频媒体通道失败 PJ_ERRNO_VIDEO_CHANNEL_UPDATE=170018 --- 不能更新视频媒体通道,失败 PJ_SUCCESS = 0 ----- 成功 其它说明:根据传入的media_type ,local_rtp_port等参数去查找对应创建的call_media会话端口而更新对应的视频通道。call_type类型要看pnas设计文档,值是跟sip设计文档中不一样的,如果很低层用到这个类型的话,请参考设计文档把值修改过来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值