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

 

posted @ 2019-09-19 16:17  ~清风煮酒~  阅读(295)  评论(0编辑  收藏  举报