zoukankan      html  css  js  c++  java
  • 【python3的学习之路十二】面向对象高级编程

    使用__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
  • 相关阅读:
    【血型】+【星座】准到吓人
    一落叶而知秋为什么有些树到冬天要落叶?
    WebDAV介绍
    Ruby concurrency explained
    lexus.cnblogs.com
    微博拉近了大家的距离
    High Performance Ruby Part 3: nonblocking IO and web application scalability
    Taglib确实减轻了开发负担[转]
    php中urldecode()和urlencode()起什么作用啊
    header中ContentDisposition的作用
  • 原文地址:https://www.cnblogs.com/CSgarcia/p/9706378.html
Copyright © 2011-2022 走看看