使用__slots__:
创建给实例绑定一个方法或属性操作,对另一个实例不起作用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Student(object): pass #为实例创建属性 s=Student() s.name='Mickle' print(s.name) #为实例创建方法 def set_age(self,age): self.age=age from types import MethodType s.set_age=MethodType(set_age,s) s.set_age(23) print(s.age) #对一个实例创建的方法或属性对另一个实例不起作用 #因此可以对类创建属性和方法,对所有实例都有效 def setscore(self,score): self.score=score Student.setscore=setscore m=Student() m.setscore(123) print(m.score)
使用__slots__来限制,只允许对对Student实例添加name
和age
属性。
class Student(object): __slots__ = ('name', 'age') # 用tuple定义允许绑定的属性名称 >>> s = Student() # 创建新的实例 >>> s.name = 'Michael' # 绑定属性'name' >>> s.age = 25 # 绑定属性'age' >>> s.score = 99 # 绑定属性'score' Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Student' object has no attribute 'score'
使用__slots__时请注意,如果子类继承一个有__slots__的父类,这个操作对子类不起作用,除非子类本身也使用了__slots__
使用@property:在绑定属性的时候,如果我们直接暴露属性,虽然写起来很简单,但是,没有办法检查参数,导致可以把数据随便改,可以通过设置getAttr(),或者setAttr()方法来实现如下
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!
然而上面的方法,比较复杂 没有直接用属性简单, 可以通过@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 = 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!
定制类
__str__主要是在print()的时候调用,而__repr__()返回程序开发者看到的字符串,即直接写变量不用print()
使用枚举类
from enum import Enum Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
#遍历enum
for name,member in Month.__menbers__.items():
print(name,'=>',member,',',member.value)
输出如下
Jan => Month.Jan , 1
from enum import Enum, unique @unique class Weekday(Enum): Sun = 0 # Sun的value被设定为0 Mon = 1 Tue = 2 Wed = 3 Thu = 4 Fri = 5 Sat = 6
>>> day1 = Weekday.Mon
>>> print(day1)
Weekday.Mon
>>> print(Weekday.Tue)
Weekday.Tue
>>> print(Weekday['Tue'])
Weekday.Tue
>>> print(Weekday.Tue.value)
2
>>> print(day1 == Weekday.Mon)
True
>>> print(day1 == Weekday.Tue)
False
>>> print(Weekday(1))
Weekday.Mon
>>> print(day1 == Weekday(1))
True