python3学习笔记 定制类

__str__

class Student(object):
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return 'Student object (name: %s)' % self.name
  __repr__ = __str__

#作用:可以直接打印内部信息
>>> print(Student('Michael')) Student object (name: Michael)

__getattr__

当调用不存在的属性时,比如score,Python解释器会试图调用__getattr__(self, 'score')来尝试获得属性,这样,我们就有机会返回score的值:

class Student(object):

    def __init__(self):
        self.name = 'Michael'

    def __getattr__(self, attr):
        if attr=='score':
            return 99

>>> s = Student()
>>> s.name
'Michael'
>>> s.score
99
 
#返回函数也是完全可以的:
class
Student(object): def __getattr__(self, attr): if attr=='age': return lambda: 25
只是调用方式要变为:
>>> s.age()
25

任意调用如s.abc都会返回None,这是因为我们定义的__getattr__默认返回就是None。要让class只响应特定的几个属性,我们就要按照约定,抛出AttributeError的错误:

class Student(object):

    def __getattr__(self, attr):
        if attr=='age':
            return lambda: 25
        raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)

这实际上可以把一个类的所有属性和方法调用全部动态化处理了,不需要任何特殊手段。

作用实例:

利用完全动态的__getattr__,我们可以写出一个链式调用:

class Chain(object):

    def __init__(self, path=''):
        self._path = path

    def __getattr__(self, path):
        return Chain('%s/%s' % (self._path, path))

    def __str__(self):
        return self._path

    __repr__ = __str__




>>> Chain().status.user.timeline.list
'/status/user/timeline/list'
这样,无论API怎么变,SDK都可以根据URL实现完全动态的调用,而且,不随API的增加而改变!

__call__

任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用。

class Student(object):
    def __init__(self, name):
        self.name = name

    def __call__(self):
        print('My name is %s.' % self.name)


调用方式如下:
>>> s = Student('Michael')
>>> s() # self参数不要传入
My name is Michael.

猜你喜欢

转载自www.cnblogs.com/zsypython/p/8933210.html