Python练习task11:魔法方法

Python 的对象天生拥有一些神奇的方法,它们总被双下划线所包围,他们是面向对象的 Python 的一切。
他们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而这一切都是自动发生的。

__ init__ 和__ new__

__ init__和__new__共同构成了构造函数。__init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值。
__new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法。__new__在__init__之前被调用,__new__的返回值(实例)将传递给__init__方法的第一个参数,然后__init__给这个实例设置一些参数。

class Person(object):
    def __new__(cls, *args, **kwargs):
        print(args)
        return object.__new__(cls)

if "__name__"=="__main__":
    person=Person('meng')

在这里插入图片描述

__ str__和__repr__

其实__str__相当于是str()方法 而__repr__相当于repr()方法。str是针对于让人更好理解的字符串格式化,而repr是让机器更好理解的字符串格式化。

class Test(object):
    def __init__(self, world):
        self.world = world
    def __str__(self):
        return 'world is %s str' % self.world
    def __repr__(self):
        return 'world is %s repr' % self.world

t = Test('python')
print(str(t))
print(repr(t))

在这里插入图片描述

__ hash__和__dir__

__hash__是hash()方法的装饰器版本,而__dir__是dir()的装饰器版本。

class Test(object):
    def __init__(self, world):
        self.world = world
x = Test('world')
p = Test('world')
print(hash(x)==hash(p))
print(hash(x.world)==hash(p.world))

class Test2(object):
    def __init__(self, song):
        self.song = song
    def __hash__(self):
        return 1241
x = Test2('popo')
p = Test2('janan')

print(x, hash(x))
print(p, hash(p))

在这里插入图片描述
可以看到这里的hash()方法总是会返回int型的数字。可以用于比较一个唯一的对象,比方说一个不同内存的object不会相当,而相同字符串hash之后就会相等。然后我们通过修改__hash__方法来修改hash函数的行为。让他总是返回1241,也是可以轻松做到的。

另外一个方法是dir(),熟悉python的人都知道dir()可以让我们查看当前环境下有哪些方法和属性可以进行调用。如果我们使用dir(object)语法,可以获得一个对象拥有的方法和属性。同样的道理如果我们在类中定义了__dir__(),就可以指定哪些方法和属性能够被dir()方法所查看查找到。

__ getattr__, __ setattr__, __ delattr__, __ getattribute__

__getattr__是一旦我们尝试访问一个并不存在的属性的时候就会调用,而如果这个属性存在则不会调用该方法。

class Test(object):
    def __init__(self, world):
        self.world = world
    def __getattr__(self, item):
        return item
        
x = Test('world123')
print(x.world4)

在这里插入图片描述
这里我们并没有world4属性,在找不到属性的情况下,正常的继承object的对象都会抛出AtrributeError的错误。但是这里我通过__getattr__魔法方法改变了找不到属性时候的类的行为。输出了查找的属性的参数。

__setattr__是设置参数的时候会调用到的魔法方法,相当于设置参数前的一个钩子。每个设置属性的方法都绕不开这个魔法方法,只有拥有这个魔法方法的对象才可以设置属性。在使用这个方法的时候要特别注意到不要被循环调用了。

class Test(object):
    def __init__(self, world):
        self.world = world
    def __setattr__(self, name, value):
        if name == 'value':
            object.__setattr__(self, name, value - 100)
        else:
            object.__setattr__(self, name, value)

x = Test(123)
print(x.world)
x.value = 200
print(x.value)

在这里插入图片描述

__delattr__的行为和__setattr__特别相似,同样需要注意的也是循环调用问题,其他都差不多,只是把属性赋值变成了 del self.name这样的表示。

class Test(object):
    def __init__(self, world):
        self.world = world
    def __delattr__(self, item):
        print('hahaha del something')
        object.__delattr__(self, item)

x = Test(123)
del(x.world)
print(x.world)

在这里插入图片描述
__getattribute__和__getattr__方法唯一不同的地方是,上面我们已经介绍了__getattr__方法只能在找不到属性的时候拦截调用,然后进行重载或者加入一些其他操作。但是__getattribute__更加强大,他可以拦截所有的属性获取。所以也容易出现我们上面提到的,循环调用的问题。

其他魔法方法

除了上述几个魔法方法外,python中还有很多魔法方法,如下:

a.基本魔法方法:
1.del(self) 析构器,当一个实例被销毁的时候调用的方法
2.call(self[,args…]) 允许一个类的实例像函数一样被调用: x(a,b) 调用 x.call(a,b)
3.len(self) 定义当被 len() 调用时的行为
4.bytes(self) 定义当被 bytes() 调用时的行为
5.bool(self) 定义当被 bool() 调用时的行为,应该返回的是True或者False
6.format(self,format_spec) 定义当被 format() 调用时的行为

b.有关属性
7.get(self,instance,owner) 定义当描述符的值被取得时的行为
8.set(self,instance,value) 定义当描述符的值被改变时的行为
9.delete(self,instance) 定义当描述符的值被删除时的行为

c.比较操作符
10.lt(self,other) 定义小于号的行为: x<y 调用 x.lt(y)
11.le(self,other) 定义小于等于号的行为: x<=y 调用 x.le(y)
12.eq(self,other) 定义等于号的行为: x==y 调用 x.eq(y)
13.ne(self,other) 定义不等号的行为: x!=y 调用 x.ne(y)
14.gt(self,other) 定义大于号的行为: x>y 调用 x.gt(y)
15.ge(self,other) 定义大于等于号的行为: x>=y 调用 x.ge(y)

d.算法运算符
16.add(self,other) 定义加法的行为: +
17.sub(self,other) 定义减法的算法: -
18.mul(self,other) 定义乘法的行为: *
19.truediv(self,other) 定义真除法的行为: /
20.floordiv(self,other) 定义整数除法(地板除)的行为: //
21.mod(self,other) 定义取模算法的行为: %
22.divmod(self,other) 定义当被 divmod() 调用时的行为
23.pow(self,other[,modulo]) 定义当被 power() 调用或**运算时的行为
24.lshift(self,other) 定义按位左移的行为:<<
25.rshift(self,other) 定义按位右移的行为:>>
26.add(self,other) 定义按位与操作的行为:&
27.xor(self,other) 定义按位异或操作的行为:^
28.or(self,other) 定义按位或操作的行为:|

e.反运算
29.radd(self,other) 与上方相同,当左操作数不支持相应的操作时被调用
30.rsub(self,other) 与上方相同,当左操作数不支持相应的操作时被调用
31.rmul(self,other) 与上方相同,当左操作数不支持相应的操作时被调用
32.rtruediv(self,other) 与上方相同,当左操作数不支持相应的操作时被调用
33.rfloordiv(self,other) 与上方相同,当左操作数不支持相应的操作时被调用
34.rmod(self,other) 与上方相同,当左操作数不支持相应的操作时被调用
35.rdivmod(self,other) 与上方相同,当左操作数不支持相应的操作时被调用
36.rpow(self,other) 与上方相同,当左操作数不支持相应的操作时被调用
37.rlshift(self,other) 与上方相同,当左操作数不支持相应的操作时被调用
38.rrshift(self,other) 与上方相同,当左操作数不支持相应的操作时被调用
39.rxor(self,other) 与上方相同,当左操作数不支持相应的操作时被调用
40.ror(self,other) 与上方相同,当左操作数不支持相应的操作时被调用

f.增量赋值运算
41.iadd(self, other) 定义赋值加法的行为:+=
42.isub(self, other) 定义赋值减法的行为:-=
43.imul(self, other) 定义赋值乘法的行为:*=
44.itruediv(self, other) 定义赋值真除法的行为:/=
45.ifloordiv(self, other) 定义赋值整数除法的行为://=
46.imod(self, other) 定义赋值取模算法的行为:%=
47.ipow(self, other[, modulo]) 定义赋值幂运算的行为:**=
48.ilshift(self, other) 定义赋值按位左移位的行为:<<=
49.irshift(self, other) 定义赋值按位右移位的行为:>>=
50.iand(self, other) 定义赋值按位与操作的行为:&=
51.ixor(self, other) 定义赋值按位异或操作的行为:^=
52.ior(self, other) 定义赋值按位或操作的行为:|=

g.一元操作符
53.neg(self) 定义正号的行为:+x
54.pos(self) 定义负号的行为:-x
55.abs(self) 定义当被 abs() 调用时的行为
56.invert(self) 定义按位求反的行为:~x

h.类型转换
57.complex(self) 定义当被 complex() 调用时的行为(需要返回恰当的值)
58.int(self) 定义当被 int() 调用时的行为(需要返回恰当的值)
59.float(self) 定义当被 float() 调用时的行为(需要返回恰当的值)
60.round(self[, n]) 定义当被 round() 调用时的行为(需要返回恰当的值)
61.index(self)
①当对象是被应用在切片表达式中时,实现整形强制转换
② 如果你定义了一个可能在切片时用到的定制的数值型,你应该定义 index
③如果 index 被定义,则 int 也需要被定义,且返回相同的值

i.上下文管理(with 语句)
62.enter(self)
①定义当使用 with 语句时的初始化行为
②__enter__ 的返回值被 with 语句的目标或者 as 后的名字绑定
63.exit(self, exc_type, exc_value, traceback)
①定义当一个代码块被执行或者终止后上下文管理器应该做什么
② 一般被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作

j.容器类型
64.len(self) 定义当被 len() 调用时的行为(返回容器中元素的个数)
65.getitem(self, key) 定义获取容器中指定元素的行为,相当于 self[key]
66.setitem(self, key, value) 定义设置容器中指定元素的行为,相当于 self[key] = value
67.delitem(self, key) 定义删除容器中指定元素的行为,相当于 del self[key]
68.iter(self) 定义当迭代容器中的元素的行为
69.reversed(self) 定义当被 reversed() 调用时的行为
70.contains(self, item) 定义当使用成员测试运算符(in 或 not in)时的行为

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值