OPP一些鸡零狗碎

1.鸭子类型

  动态语言的“鸭子类型”,它并不要求严格的继承体系,一个对象只要“看起来像鸭子,走起路来像鸭子”,那它就可以被看做是鸭子。

  对于静态语言(例如Java)来说,如果需要传入Animal类型,则传入的对象必须是Animal类型或者它的子类,否则,将无法调用run()方法。

  对于Python这样的动态语言来说,则不一定需要传入Animal类型。我们只需要保证传入的对象有一个run()方法就可以了:

  例如:Python的“file-like object“就是一种鸭子类型。对真正的文件对象,它有一个read()方法,返回其内容。但是,许多对象,只要有read()方法,都被视为“file-like object“。

  许多函数接收的参数就是“file-like object“,你不一定要传入真正的文件对象,完全可以传入任何实现了read()方法的对象。

 

2.获取对象信息

1)获取对象属性,方法  dir()

>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']

   __xxx__方法,一般有特殊用途,eg:__length__

>>> len('ABC')
3
>>> 'ABC'.__len__()
3
#----我们自己写的类,如果也想用len(myObj)的话,就自己写一个__len__()方法:

>>> class MyDog(object):
...     def __len__(self):
...         return 100
...
>>> dog = MyDog()
>>> len(dog)
100

2)hasattr:检测是否存在属性

>>> class MyObject(object):
...     def __init__(self):
...         self.x = 9
...     def power(self):
...         return self.x * self.x
...
>>> obj = MyObject()
#---------------------------
>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False

3)getattr和setattr

>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19
#如果试图获取不存在的属性,会抛出AttributeError的错误: >>> getattr(obj, 'z') # 获取属性'z' Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'MyObject' object has no attribute 'z' #可以传入一个default参数,如果属性不存在,就返回默认值: >>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404 404 #也可以获得对象的方法: >>> hasattr(obj, 'power') # 有属性'power'吗? True >>> getattr(obj, 'power') # 获取属性'power' <bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>> >>> fn = getattr(obj, 'power') # 获取属性'power'并赋值到变量fn >>> fn # fn指向obj.power <bound method MyObject.power of <__main__.MyObject object at 0x10077a6a0>> >>> fn() # 调用fn()与调用obj.power()是一样的 81

 

3.@property装饰器

负责把一个方法变成属性调用

使用前

class Student(object):

    def get_score(self):
         return self._score

    def set_score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value

#----------------------
>>> s = Student()
>>> s.set_score(60) # ok!
>>> s.get_score()
60
>>> s.set_score(9999)
Traceback (most recent call last):
  ...
ValueError: score must between 0 ~ 100!

使用后

(只定义getter方法,不定义setter方法就是一个只读属性,下例中age是只读属性,birth和score是可读写属性)

class Student(object):

    @property
    def age(self):
        return 2015 - self._birth

    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value

    @property
    def score(self):
        return self._score

    @score.setter
    def score(self, value):
        if not isinstance(value, int):
            raise ValueError('score must be an integer!')
        if value < 0 or value > 100:
            raise ValueError('score must between 0 ~ 100!')
        self._score = value
    
#----------------------
>>> s = Student()
>>> s.score = 60 # OK,实际转化为s.set_score(60)
>>> s.score # OK,实际转化为s.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
  ...
ValueError: score must between 0 ~ 100!

 

4.多重继承

  OPP一些鸡零狗碎

#设计类
class Animal(object):
    pass

# 大类:
class Mammal(Animal):
    pass

class Bird(Animal):
    pass

# 各种动物:
#class Dog(Mammal):
    #pass

class Dog(Mammal, Runnable):
    pass

#class Bat(Mammal): 
  #pass 

class Bat(Mammal, Flyable):
    pass

#class Parrot(Bird): 
  #pass 

#class Ostrich(Bird): 
  #pass 

#跑/飞类 

class Runnable(object): 
 
  def run(self): 
    print('Running...') 

class Flyable(object): 
    def fly(self): 
            print('Flying...')
            

 

MixIn

  给一个类增加多个功能,这样,在设计类的时候,我们优先考虑通过多重继承来组合多个MixIn的功能,而不是设计多层次的复杂的继承关系。

 

上一篇:android studio的汉化 教程 及解析


下一篇:Project Euler 004