Python 面向对象高级编程——定制类

1.1   定制类

1.1.1   __str__

>>> class Student(object):

...    def __init__(self, name):

...        self.name = name

...

>>> s = Student(‘daidai‘)

>>> s.name

‘daidai‘

>>> Student(‘daidai‘).name

‘daidai‘

>>> print(Student(‘daidai‘))     --发现这样打印并不好看

<__main__.Student object at0x2ac5ebc99128>

>>> class Student(object):

...    def __init__(self, name):

...        self.name = name

...    def __str__(self):

...         return ‘Student object (name: %s)‘ %self.name

...

>>> print(Student(‘daidai‘))

Student object (name: daidai)

>>> s = Student(‘daidai‘)

>>> s         --指向变量后,仍然不好看

<__main__.Student object at0x2ac5ebc99160>

>>> s.name

‘daidai‘

将__str__同时指向__repr__

>>> class Student(object):

...    def __init__(self, name):

...        self.name = name

...    def __str__(self):

...        return ‘Student object (name: %s)‘ % self.name

...    __repr__ = __str__

...

>>> print(Student(‘daidai‘))

Student object (name: daidai)

>>> s = Student(‘daidai‘)

>>> s.name

‘daidai‘

>>> s

Student object (name: daidai)

1.1.2   __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 > 10000:            #退出循环条件

...             raiseStopIteration();

...        return self.a              #返回下一个值

...

>>> for n in Fib():

...    print(n)

...

1

1

2

3

5

8

13

21

34

55

89

144

233

377

610

987

1597

2584

4181

6765

1.1.3   __getitem__

上述Fib实例感觉和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

...

>>> f = Fib()

>>> f[0]

1

>>> f[4]

5

>>> f[88]

1779979416004714189

1.1.4   __getattr__

正常情况下,当我们调用类的方法或属性时,如果不存在,就会报错。

>>> class Student(object):

...    def __init__(self):

...        self.name = ‘daidai‘

...

>>> s = Student()

>>> print(s.name)

daidai

>>> print(s.score)

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

AttributeError: ‘Student‘ object has noattribute ‘score‘

加上__getattr__动态返回属性值

>>> class Student(object):

...    def __init__(self):

...        self.name = ‘daidai‘

...    def __getattr__(self, attr):       --当输入score不存在时,python动态调用这个方法

...         if attr == ‘score‘:

...             return 98

...

>>> s = Student()

>>> s.name

‘daidai‘

>>> s.score

98

__getattr__返回函数也是可行的

>>> class Student(object):

...    def __getattr__(self, attr):

...         if attr == ‘age‘:

...             return lambda : 24

...

>>> s = Student()

>>> s.age

<functionStudent.__getattr__.<locals>.<lambda> at 0x2ac5ebc8e730>

>>> s.age()

24

只有在没有找到属性的情况下,才调用__getattr__,已有的属性,比如name,不会在__getattr__中查找。

>>> class Student(object):

...    def __getattr__(self, attr):

...        if attr == ‘age‘:

...             return lambda : 24

...        raise AttributeError(‘\‘Student\‘ object has no attribute \‘%s\‘‘ %attr)

...

>>>

>>> s = Student()

>>> s.name

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

File "<stdin>", line 5, in __getattr__

AttributeError: ‘Student‘ object has noattribute ‘name‘

>>> s.age

<functionStudent.__getattr__.<locals>.<lambda> at 0x2ac5ebc8e488>

>>> s.age()

24

1.1.5   __call__

__call__方法能实现直接在实例本身上调用。

>>> class Student(object):

...    def __init__(self, name):

...        self.name = name

...    def __call__(self):

...         print(‘My name is %s.‘ % self.name)

...

>>> s = Student(‘daidai‘)

>>> s

<__main__.Student object at0x2ac5ebc99748>

>>> s()      --直接实例对象调用

My name is daidai.

可通过callable判断对象是否可调用

>>>callable(Student(‘daidai‘))

True

>>> callable(max)

True

>>> callable((1, 2, 3))

False

>>> callable(‘str‘)

False

__call__也可传入参数

>>> class Student(object):

...    def __init__(self, name):

...        self.name = name

...    def __call__(self, others):

...         print(‘My name is %s, %s‘ %(self.name, others))

...

>>>

>>> s = Student(‘daidai‘)

>>> s(‘so handsome.‘)

My name is daidai, so handsome.

时间: 2024-10-09 04:19:32

Python 面向对象高级编程——定制类的相关文章

Python 面向对象高级编程——使用枚举和元类

1.1   使用枚举 基于Enum类实现的枚举 >>> fromenum import Enum >>> Month = Enum('Month', ('Jan','Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec')) >>> for name, member inMonth.__members__.items(): ...    print(name,

python面向对象高级编程

python中属性和方法的动态绑定  class Student(object):     pass   # 实例化一个对象     s = Student() # 给这个对象绑定一个属性name s.name = 'John'   print(s.name) John   # 定义一个方法 def set_age(self, age):     self.age = age   # 导入模块     from types import MethodType   #给s这个对象绑定一个set_a

python Class:面向对象高级编程 元类:type

type的用法: 1.普通的type用法:检查类型 class my(object):     def hello(self, name='world'):         print('Hello, %s.' % name) h = my()        print(type(my))         print(type(h)) 运行结果: <type 'type'> <class '__main__.my'> my是class, 所以它的类型是type, h是class的实

Python面向对象高级编程:@property--把方法变为属性

为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数: 1 >>> class Student(object): 2 def get_score(self): 3 return self.__score 4 def set_score(self,value): 5 if not isinstance(value,int): 6 raise ValueError('sec

Python 面向对象高级编程——使用@property

1.1   使用@property 输入成绩score时,需对这个参数进行检查. >>> class Student(object): ...    def get_score(self): ...        return self.__score ...    def set_score(self, value): ...        if not isinstance(value, int): ...             raise ValueError('score mu

Python面向对象高级编程[email&#160;protected]

使用@property 在绑定属性时,如果直接把属性暴露出去,虽然写起来简单,但是没法检查参数,导致可以把成绩随便改: >>> class Student(object): pass >>> s =Student() >>> s.score=999 >>> s.score 999 这显然不符合逻辑,为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_s

Python 面向对象高级编程——使用__slots__

1.1   使用__slots__ 1.1.1   类方法的绑定 实例上添加方法 >>> class Student(object): ...    pass ... >>> def set_age(self, age):     #定义函数作为实例方法,注意self参数 ...    self.age = age ... >>> s = Student() >>> fromtypes import MethodType >&g

Python 面向对象高级编程——多重继承

1.1   多重继承 >>> #最大类 ... class Animal(object): ...    pass ... >>> #大类 ... class Mammal(Animal): ...    pass ... >>> class Bird(Animal): ...    pass ... >>> class Runnable(object): ...    def run(self): ...        print(

Python面向对象高级编程-_slots_

使用_slots_ 正常情况下,当定义一个class,创建一个class的实例后,可以给实例绑定任何属性和方法,这就是动态语言的灵活性.先定义class: >>> class Student(object): pass 然后,尝试给实例绑定一个属性: >>> s = Student() >>> s.name = 'Michael' >>> print s.name Michael 还可以尝试给实例绑定一个方法: >>>