类和对象-__call__
>>> #只要定义了__call__()方法,Python便可以像调用函数一样去调用该对象,不仅支持位置参数和关键字参数,还可以用作闭包的简易实现!内置函数repr()与str()运行结果常常相同,但设计初衷不同——str()将参数转换为字符串,给人看;
repr()将对象转换为程序可执行的字符串,给程序(机器)看。
被repr()转化后的字符串可以被内置函数eval()去引号后执行,其结果往往就是原参数,故eval()可以理解为repr()的反函数。
魔法方法__str__()和__repr__()分别对应str()和repr(),二者均返回字符串,且__repr__()可作为__str__()的代偿(反之不成立)。
不过,通过__str__()定义的只能应用于对象出现在打印操作的顶层,
但__repr__()则不同,其适用场景更多,用起来也更安全!
最后,同时定义两个方法可以让对象在不同场景下实现不同的显示效果,既灵活又有趣!
>>> #__call__():在对象中既可以有属性又可以有方法,python可以像调用函数一样去调用一个对象,要求就是需要这个对象的类定义__call__()魔法方法
>>> class C:
... def __call__(self):
... print('Hello')
...
>>> c = C()
>>> c()
Hello
>>> class C():
... def __call__(slef, *args, **kwargs):
... print(f'位置参数 -> {args}\n关键字参数 -> {kwargs}')
...
>>> c = C()
>>> c(1, 2, 3, x=250, y=520)
位置参数 -> (1, 2, 3)
关键字参数 -> {'x': 250, 'y': 520}
>>> #用__call__()函数实现闭包的效果
>>> class Power:
... def __init__(self, exp):
... self.exp = exp
... def __call__(self, base):
... return base ** self.exp
...
>>> square = Power(2)
>>> cube = Power(3)
>>> square(5)
25
>>> cube(3)
27
>>> #跟字符串相关的魔法方法:__str__()和__repr__() P168
>>> #__repr__()对应repr()函数,str()函数将参数转换为字符串对象,是给人看的;
repr函数将对象转换为程序可执行的字符串,是给程序看的
>>> #repr()与eval()互被称为反函数,eval()作用为将参数去引号后执行,并且得到结果。
repr()函数返回的字符串作为参数传递给eval()函数的话,那么所得到的结果必定是repr()函数的参数
>>> repr("print('crazy')")
'"print(\'crazy\')"'
>>> str("print('crazy')")
"print('crazy')"
>>> #repr()返回的带引号,str()返回的不带引号
>>> eval("print('crazy')")
crazy
>>> eval(repr('crazy'))
'crazy'
>>> try:
... eval(str('crazy'))
... except NameError as e:
... print(e)
...
name 'crazy' is not defined
>>> #str('crazy')的返回值为crazy,不带引号,python会将其作为变量名来引用,结果就是找不到的定义fishc的变量
>>> #repr()返回的是带引号的'crazy',eval(repr('crazy'))会执行
>>> eval(repr("print('crazy')"))
"print('crazy')"
>>> eval(repr(print('carzy')))
carzy
>>> eval(str("print('crazy')"))
crazy
>>> eval(str(print('crazy')))
crazy
>>> #代偿:__str__() -> __repr__(),repr代偿str,反过来不行
>>> class C:
... def __repr__(self):
... return 'i love you'
...
>>> c = C()
>>> print(repr(c))
i love you
>>> print(str(c))
i love you
>>> #__str__()魔法方法定义的,只能应用于对象出现在打印操作的顶层,即如果把多个对象放到一个列表中,然后打印该列表的话,那么就没办法访问到对应的字符串了
>>> cs =
>>> for each in cs:
... print(each)
...
i love you
i love you
i love you
>>> print(cs)
>>> #__repr__()可以访问到每个cs的元素
>>> class C:
... def __str__(self):
... return 'i love you'
...
>>> cs =
>>> print(cs)
[<__main__.C object at 0x01EAE3A0>, <__main__.C object at 0x01EAE5B0>, <__main__.C object at 0x01EAE4F0>]
>>> class C:
... def __init__(self, data):
... self.data = data
... def __str__(self):
... return f'data = {self.data}'
... def __repr__(self):
... return f'C({self.data})'
... def __add__(self, other):
... self.data += other
...
>>> c = C(250)
>>> print(c)
data = 250
>>> print(repr(c))
C(250)
>>> c + 250
>>> print(c)
data = 500
>>> print(repr(c))
C(500)
页:
[1]