""" """
__author__ =
'shaozhiqi'
# Python的class中还有许多有特殊用途的函数,可以帮助我们定制类
# ------------------str-----------------------------------
class Student(object):
def __init__(self, name):
self.name =
name
print(Student(
'shaozhiqi'))
# <__main__.Student object at 0x00000000022137C8>
class Student(object):
def __init__(self, name):
self.name =
name
def __str__(self):
return 'Student object (name: %s)' %
self.name
__repr__ =
__str__
print(Student(
'shaozhiqi'))
# Student object (name: shaozhiqi)
# 直接敲变量不用print,打印出来的实例还是之前的那种编码
# 直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。
# 再定义一个__repr__(),由于函数体一样,就直接赋值了
# --------------------------iter------------------------------------
# 如果一个类想被用于for ... in循环,类似list或tuple那样,
# 就必须实现一个__iter__()方法,该方法返回一个迭代对象,
# Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1
# 初始化两个计数器a,b
def __iter__(self):
return self
# 实例本身就是迭代对象,故返回自己
def __next__(self):
self.a, self.b = self.b, self.a + self.b
# 计算下一个值
if self.a > 100000:
# 退出循环的条件
raise StopIteration()
return self.a
# 返回下一个值
for n
in Fib():
print(n)
# -------------------------------------------__getitem__-------------------
# Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,比如,取第5个元素:
# Fib()[5] # error
# 要可以得像list那样按照下标取出元素,需要实现__getitem__()方法:
class Fib(object):
def __getitem__(self, n):
a, b = 1, 1
for x
in range(n):
a, b = b, a +
b
return a
print(Fib()[5])
# 8
# --------------------------__getattr__ ----------------------
# 之前有接触,当我们调用类的方法或属性时,如果不存在,就会报错。
# 比如Student 么有score这个属性 访问会报错。
# 要避免这个错误,除了可以加上一个score属性外,Python还有另一个机制,
# 那就是写一个__getattr__()方法,动态返回一个属性。修改如下:
class Student(object):
def __init__(self):
self.name =
'shaozhiqi'
def __getattr__(self, attr):
if attr ==
'score':
return 99
raise AttributeError(
'\'Student\' object has no attribute \'%s\'' %
attr)
s =
Student()
print(s.name)
# shaozhiqi
print(s.score)
# 99
# print(s.age) # AttributeError: 'Student' object has no attribute 'age'
# 没有找到属性的情况下,才调用__getattr__,已有的属性,比如name,不会在__getattr__中查找。
# --------------------------------------------__call__-------------------------------
# 任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用
class Student(object):
def __init__(self, name):
self.name =
name
def __call__(self):
print(
'My name is %s.' %
self.name)
s = Student(
'shaozhiqi')
print(
'name:', s.name)
# name: shaozhiqi
s()
# My name is shaozhiqi. 可以不用.方法名或者属性名去调用
# 能被调用的对象就是一个Callable对象,比如函数和我们上面定义的带有__call__()的类实例:
print(callable(Student))
# True
print(callable(max))
# True
print(callable(
'abc'))
# False
转载于:https://www.cnblogs.com/shaozhiqi/p/11550592.html