magic method

什么是魔术方法

魔术方法是python语言预定好的”协议”,不同魔术方法在不同场景下,会被隐式调用.我们通过重写这些方法,从而操控各种行为.
eg:

class A(object):  
     def __str__(self):  
         return "I am A,2333" 
     def __len__(self):  
         return 42 
 a = A()  
 print a#输出 "I am A,2333"  
 print len(a)#输出42 

可以看到,print语句会隐式调用str方法,len()会隐式调用len方法.

常用的魔术方法

构造与初始化
new(cls)
new 是一个类的初始化过程中第一个被执行的方法。它创建了类的对象,并返回,然后把一些参数传递给init
init(self)
类的构造器,当初始构造方法被执行(例如,我们执行 x = SomeClass(10,’foo’)),init 就会获得 10 和 ‘foo’ 作为参数。init 在python类的定义中经常被使用
del(self)
python中的垃圾回收机制工作时会用到,实际中很少用到

class Programer(object):
    def __new__(cls,*args,**kwargs):
        print('call __new__ method')
        print(args)
        return super(Programer,cls).__new__(cls)  
    def __init__(self,name,age):
        print('call __init__ method')
        self.name=name
        self.age=agef __name__=='_main_':
programer=Programer('nick',19)
print programer.__dict__ 
#call __new__ method
#('nick',19)
#call __init__ method
#{'name':'nick','age':19}   

逻辑运算符
cmp(self, other)
cmp 是关于比较的“魔法”方法中最基础的方法。其实它已经实现了所有关于比较的操作(<, ==, !=, 等等.),但是有时这并不是我们想要的(例如,如何判断一个类的实例是否等于另一个实例,或是如何判断是否一个实例大于另一个实例)。cmp 方法,如果 self < other ,它会返回一个负整数。如果 self == other , 它会返回 0 。如果self > other ,它会返回正整数。通常定义一次要比每次需要比较的时候都定义要好的多,事实上 cmp 是一种非常好的方法在所有的比较方法有相似的逻辑的时候,它让我们减少重复和提高了代码清晰度。
eq(self, other)
定义等于操作的行为,==。
ne(self, other)
定义不等于操作的行为。!=。
lt(self, other)
定义小于操作的行为,<。
gt(self, other)
定义大于操作的行为,>。
le(self, other)
定义小于等于操作的行为,<=。
ge(self, other)
定义大于等于操作的行为,>=。

#coding:utf-8
class Programer(object):
    def __init__(self,name,age):
        self.name=name
        if isinstance(age,int):  
            self.age=age
        else:
            raise Exception('age must be int')
    def __eq__(self,other):  #根据age判断大小
        if isinstance(other,Programer):
            if self.age==other.age:
                return True
            else:
                return False
        else:
            raise Exception('The type of object must be Programer')
    def __add__(self,other):  #根据age实现加法
        if isinstance(other,Programer):  
            return self.age+other.age
        else:
            raise Exception('The type of object must be Programer')     
p1=Programer('nick',19)
p2=Programer('Bill',50)
print(p1==p2)
print(p1+p2)
#False
#69

通过重写eq()方法和add方法,实现根据对象的不同属性进行比较和算术运算

add(self, other)

实现一个加法.

sub(self, other)

实现一个减法.

mul(self, other)

实现一个乘法.

floordiv(self, other)

实现一个“//”操作符产生的整除操作

div(self, other)

实现一个“/”操作符代表的除法操作.

truediv(self, other)

实现真实除法,注意,只有当你from future import division时才会有效

mod(self, other)

实现一个“%”操作符代表的取模操作.
pow

实现一个指数操作(“**”操作符)的行为

lshift(self, other)

实现一个位左移操作(<<)的功能

rshift(self, other)

实现一个位右移操作(>>)的功能.

and(self, other)

实现一个按位进行与操作(&)的行为.

or(self, other)

实现一个按位进行或操作(|)的行为.

xor(self, other)

实现一个异或操作(^)的行为

pos(self)

实现一个取正数的操作(比如 +some_object ,python调用pos函数)

neg(self)

实现一个取负数的操作(比如 -some_object )

abs(self)

实现一个内建的abs()函数的行为

invert(self)

实现一个取反操作符(~操作符)的行为。想要了解这个操作的解释,参考the Wikipedia article on bitwise operations.

round(self, n)

实现一个内建的round()函数的行为。 n 是待取整的十进制数.

floor(self)

实现math.floor()的函数行为,比如, 把数字下取整到最近的整数.

ceil(self)

实现math.ceil()的函数行为,比如, 把数字上取整到最近的整数.

trunc(self)

实现math.trunc()的函数行为,比如, 把数字截断而得到整数.

类的展现
在Python中,有很多你可以在类定义中实施的方法来自定义内置函数的返回值以表示出你所写出的类的某些行为
str(self)
返回的是人类可读的输出
repr(self)
返回的是机器可读的输出
unicode(self)
返回unicode字符串
format(self, formatstr)
定义当你的一个类的实例被用来用新式的格式化字符串方法进行格式化时所要产生的行为。例如, “Hello, {0:abc}!”.format(a) 将会导致调用 a.format(“abc”) 。这对定义你自己的数值或字符串类型是十分有意义的,你可能会给出一些特殊的格式化选项。
dir(self)
该方法应该返回一个属性的列表给用户,通过重写该方法,返回要求的属性列表
sizeof(self)
该方法以字节为单位,返回对象的大小。

#coding:utf-8
class Programer(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):  #返回指定内容字符串
        return('%s is %s years old'%(self.name,self.age))
    def __dir__(self):  #返回指定属性
        return(self.__dict__.keys())        
p=Programer('nick',19)
print(p)
print(dir(p))
#nick is 19 years old
#['age','name']

类的访问控制
setattr(self, name, value)
setattr是一个真正的封装方案,它允许你定义当给一个存在或不存在的属性赋值时的行为,意味着对任何属性值的改变你都可以定义一个规则。
delattr
删除对象属性(与setattr非常像)
•查询对象属性
getattr(self, name)
你可以试图访问一个不存在(不存在或还没创建)的属性。
getattribute(self, name)
每次访问属性都会调用到。

#coding:utf-8
class Programer(object):
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __getattribute__(self,name):  
        return(super(Programer,self).__getattribute__(name))
    def __setattr__(self,name,value):  
        self.__dict__[name]=value       
p=Programer('nick',19)
print(p.name)
#nick
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值