python3(二十九) orderClass
""" """ __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