使用__slots__

为了达到限制实例的属性的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制class实例能添加的属性。

class Student(object):
    __slots__ = ('name', 'age')

    def set_age(self, age):
        self.age = age

class GraduateStudent(Student):
    pass

s = Student()
s.name = 'A'
s.score = 32

gs = GraduateStudent()
gs.name = 'B'
gs.score = 20

由于’score’没有被放到__slots__中,所以不能绑定score属性,但是__slots__定义的属性今对当前类实例起作用,对继承的子类是不起作用的。
除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__。

使用@property

在绑定属性时,如果我们直接把属性暴露出去,虽然写起来简单,但是,没办法检查参数,导致可以把成绩随便更改。
有没有既能检查参数,又可以用类似属性这样简单的方式来访问类的变量呢?Python内置的@property装饰器就是负责把一个方法变成属性调用的

class Student(object):

    @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 = 'nasm'
s.score = -1
s.score = 80

@property还可以定义只读属性,只定义getter方法,不定义setter方法就是一个只读属性

class Student(object):

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

    @birth.setter
    def birth(self, vaule):
        self.__birth = vaule

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

s = Student()
s.birth = 32
print(s.age)

多重继承

class Animal(object):
    pass

# 大类:
class Mammal(Animal):
    pass

class Bird(Animal):
    pass

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

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

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

class Bat(Mammal):
    pass

class Parrot(Bird):
    pass

class Ostrich(Bird):
    pass

MixIn
在设计类的继承关系时,通常,主线都是单一继承下来的,例如,Ostrich继承自Bird。但是,如果需要“混入”额外的功能,通过多重继承就可以实现,比如,让Ostrich除了继承自Bird外,再同时继承Runnable。这种设计通常称之为MixIn。

为了更好地看出继承关系,我们把Runnable和Flyable改为RunnableMixIn和FlyableMixIn。类似的,你还可以定义出肉食动物CarnivorousMixIn和植食动物HerbivoresMixIn,让某个动物同时拥有好几个MixIn

class Dog(Mammal, RunnableMixIn, CarnivorousMixIn):
    pass

使用枚举类

from enum import Enum
Month= Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)

如果需要更精确地空值枚举类型,可以从从Enum派生出自定义类

from enum, unique

@unique
class Weekday(Enum):
    Sun = 0 # Sun的value被设定为0
    Mon = 1
    Tue = 2
    Wed = 3
    Thu = 4
    Fri = 5
    Sat = 6

使用元类

metaclass(元类):先定义类。然后创建实例

# metaclass是类的模板,所以必须从`type`类型派生:
class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
        attrs['add'] = lambda self, value: self.append(value)
        return type.__new__(cls, name, bases, attrs)
class MyList(list, metaclass=ListMetaclass):
    pass
posted on 2018-09-26 13:31  Q同码  阅读(164)  评论(0编辑  收藏  举报