《Python高级编程》(四)魔术方法

定义

被设计用于重载Python的操作符或内置方法。可通过__语法定义

可用的魔术方法

创建与销毁:__init__方法
  • 注意:__init__方法并没有创建新对象(创建由__new__完成),仅为创建后的对象提供初始化数据
创建与销毁:__new__方法
  • __new__方法实际上在__init__方法之前执行,用于创建类的实例
  • __new__方法用于是静态的
    • 大多数类无需定义__new__方法。其内置实现依据足够
    • 案例:
        class MyClass(object):
            def __new__(cls, *args, **kwargs):
                instance = super(MyClass, cls).__new__(cls, *args, **kwargs)
                #pass
                return instance
创建与销毁:__del__方法
  • 在对象被销毁时调用;无论对象以何种方式销毁都会触发__del__方法执行
  • 案例
    class Xon(object):
        def __del__(self):
            print "AUUUUUUUUUUUUUUUUUU"

    print Xon()   #Xon创建对象,但并没有赋值给变量,因此python解释器不会保留该对象
    print "abc"   #内存操作导致垃圾回收器遍历表,找到Xon对象并删除它
    ===>
    <__main__.Xon object at 0x017CBA50> AUUUUUUUUUUUUUUUUUU
    abc
类型转换:strunicode、__bytes__方法
  • python中存在多个用于将复杂对象转换为简单对象或常用数据类型的魔术方法
  • python2中使用__unicode__方法,在对象传递给unicode的构造函数时被调用
  • python3中使用__bytes__方法,在对象传递给bytes的构造函数时被调用
  • 案例:python2中格式化unicode对象时首先尝试__unicode__方法:
class Which(object):
	def __str__(self):
		return 'string'
	def __unicode__(self):
		return u'unicode'

print u'this %s was used' % Which()
print 'this %s was used' % Which()
====>
this unicode was used
this string was used
类型转换:__bool__方法 对象需要界定True或False
  • python2中:命名为__nonzero__
  • python3中:命名为__bool__
类型转换:intfloat、__complex__方法
  • python2拥有单独的Long类型,因此具有__long__方法
比较:二元相等性:__eq__方法
  • 两个对象使用==操作符进行比较时被调用
  • 案例:
class Myclass(object):
	def __eq__(self, other):
		print "The following are being tested for equivalence:\n %r\n %r " % (self, other)
		return self is other
c1 = Myclass()
c2 = Myclass()
print c1 == c2
===>
False
The following are being tested for equivalence:
 <__main__.Myclass object at 0x0184ABF0>
 <__main__.Myclass object at 0x018528B0>
False
比较 二元相等性 __ne__方法:与__eq__方法功能相反
比较 相对比较:ltlegt、__ge__方法
  • 这些方法内置了用于排序对象的sorted函数
比较 相对比较:__cmp__方法:为对象定义相对比较的旧有方式。
比较 操作符重载
  • 二元操作符:普通方法、取反方法、即席方法
  • 除法:
    • python3中对两个int类型数据做除法返回float类型的数据
    • python2中可以通过导入:from future import division来可选python3的特征
一元操作符 pos(与+匹配) neg(与-匹配) invert(与~匹配)
  • 案例:
class ReversibleString(object):
	def __init__(self,s):
		self.s = s
	def __invert__(self):
		return type(self)(self.s[::-1])
	def __repr__(self):  #用于演示目的的自定义repr,因为输出时提供内存地址没有用处
		return 'ReversibleString: %s' % self.s
	def __str__(self):
		return self.s
rs = ReversibleString('The quick brown fox jumped over the lazy dogs.')
print ~rs #.sgod yzal eht revo depmuj xof nworb kciuq ehT
比较 重载常见方法
  • __len__方法
  • 案例:
class Timespan(object):
	def __int__(self, hours=0, minutes=0, seconds=0):
		self.hours = hours
		self.minutes = minutes
		self.seconds = seconds
	def __len__(self):
		return (self.hours * 3500) + (self.minutes * 60) + self.seconds

ts = Timespan(hours=2, minutes=30, seconds=1)
print len(ts)
__repr__方法:任何对象都可以定义__repr__方法
  • 对象的repr方法用于确定该对象在python交互终端中的显示方式。在大多数情况下,一个对象的类以及其内存地址并不是希望获得的值。
  • 定义repr方法可以让对象称为更有用的代表值
  • 对比:repr和str:一个对象的repr供程序员阅读,而str的用途更广泛,供人阅读
  • 案例:
class Timespan(object):
    def __init__(self, hours=0, minutes=1, seconds=2):
        self.hours = hours
        self.minutes = minutes
        self.seconds = seconds

    def __len__(self):
        return (self.hours * 3500) + (self.minutes * 60) + self.seconds

    def __repr__(self):
        return 'Timespan(hours=%s,minutes=%d,seconds=%d' % (self.hours, self.minutes, self.seconds)

print Timespan()
print Timespan(hours=2, minutes=30, seconds=0)
__hash__方法:作用是通过数字化表达式唯一标识对象
  • 当一个对象传递给散列函数时,调用其__hash__方法,其返回整型值,通常是对象id
__format__方法:可以根据python的格式化规范来格式化不同种类的对象;任何对象都能提供__format__方法
  • 案例:
from datetime import datetime

class MyDate(datetime):
	def __format__(self, sepc_str):
		if not sepc_str:
			spec_str = '%Y-%m-%d %H:%M:%S'
		return self.strftime(spec_str)
md = MyDate(2012,4,21,11)
print '{0}'.format(md)
  • instancecheck__和__subclasscheck
  • __abs__方法和__round__方法
集合
  • __contains__方法:对表达式求值时被调用,如果needle在集合中,则返回True,否则返回False
from datetime import date
class DateRangge(object):
    def __init__(self, start, end):
        self.start = start
        self.end = end

    def __contains__(self, needle):
        return self.start <= needle <= self.end


dr = DateRangge(date(2015, 1, 1), date(2015, 12, 31))
print date(2015, 4, 21) in dr  # True
print date(2012, 1, 1) in dr  # False
其他魔术方法
- __iter__和__next__实现迭代协议
- __enter__和__exit__实现上下文管理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值