1.__slots__
:限制实例可以绑定的属性。Python
中可以给实例绑定任何属性和方法,使用该变量可以对一个类的实例可以绑定的属性做一个限制。但是该限制只作用于该类,不做用于子类。如果子类中也使用该变量,那子类的限制是自身加父类的属性限制。
class Student(object):
__slots__ = ('name', 'age')
s = Student()
s.name = 'Lisa'
s.age = 23
s.score = 89
print(s.name)
print(s.age)
print(s.score)
由于使用特殊变量对属性做了限制,所以运行上述代码时,name和age属性能照常打印,而打印score属性时会报错AttributeError: 'Student' object has no attribute 'score'
2.@property
:python
中可以直接访问类的属性并赋值,这种暴露属性的方式使得属性可以被任意赋值,所以要加参数检查,使用get
和set
方法。可是使用get/set
方法时,需要调用get/set
方法。
而@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.score
s.score = 99999
E:\Anaconda3\python.exe "E:/work files/python/Project/study/property.py"
Traceback (most recent call last):
File "E:\work files\python\Project\study\property.py", line 20, in <module>
s.score = 99999
File "E:\work files\python\Project\study\property.py", line 12, in score
raise ValueError('score must between 0 ~ 100!')
ValueError: score must between 0 ~ 100!
3.多重继承:在java
中,一个类只能继承一个父类,但可以实现多个接口;在python
中,一个类可以继承多个父类,也可以实现多个接口,但是python
中,使用MixIn
来完成实现多个接口的扩展效果。MinIn
就相当于干爹,不去考虑复杂的继承关系,只去考虑单一的扩展功能,组合优于继承。
4.python中的特殊变量可以用来定制类:
__str__
:相当于java
里toString()
方法。这样打印实例时不但美观还可以提取重要数据。__repr__
与__str__
作用相同,区别是前者返回用户看到的字符串,后者返回开发者调试的字符串。
class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name:%s)' % self.name
__repr__ = __str__
print(Student('jingmei'))
E:\Anaconda3\python.exe "E:/work files/python/Project/study/special_variables.py"
Student object (name:jingmei)
Process finished with exit code 0
__iter__
:一个类想实现for循环就要实现__iter__()
方法,该方法会返回一个迭代对象,for
循环去调用这个对象的__next__
方法,拿到下一个值。以斐波那契额数列为例,定制一个可以for
循环的类Fib
class Fib(object):
def __init__(self):
self.a, self.b = 0, 1
def __iter__(self):
return self # 自身就是一个迭代对象
def __next__(self):
self.a, self.b = self.b, self.a + self.b
if self.a > 100000:
raise StopIteration()
return self.a
for x in Fib():
print(x)
1
1
2
3
5
8
13
21
...
46368
75025
Process finished with exit code 0
__getitem__
:实现__getitem__()
方法之后类就可以根据下标去取值。
class Fib(object):
def __getitem__(self, n):
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
b = Fib()
print(b[0])
print(b[1])
print(b[2])
print(b[3])
print(b[4])
1
1
2
3
5
__getattr__
:动态返回一个属性。没有找到属性时,才会调用__getattr__(self,'score')
方法去返回score
这个不存在的属性的值。该方法的默认返回值是None
class Student(object):
def __init__(self):
self.name = 'dongluo'
def __getattr__(self, attr):
if attr == 'score':
return 99
__call__
:直接调用实例本身。可以把一个实例对象看成函数。
class Student(object):
def __init__(self, name):
self.name = name
def __call__(self):
print('My name is %s.' % self.name)
s = Student('Michael')
s()
输出结果:
My name is Michael.