Python开发(人工智能/大数据/机器学习)

24.Python编程:类中特殊的__slots__变量

2018-04-24  本文已影响5人  TensorFlow开发者

前面学习了类属性和实例属性,我们已经知道:实例属性属于各个实例对象所有,互不干扰;类属性属于类所有,所有实例共享一个属性。我们设计一个Car类:

# 定义一个Car类
class Car(object):
    pass

# 创建Car类的一个实例
c = Car()

# 给实例c绑定对象属性speed,并赋值:200
c.speed = 200

# 创建Car类的一个实例
c2 = Car()
print(c2.speed)

运行结果:

Traceback (most recent call last):
  File "F:/python_projects/oop/25Car.py", line 15, in <module>
    print(c2.speed)
AttributeError: 'Car' object has no attribute 'speed'

这里的speed属性只属于c对象。Car类中没有speed类属性,如果该类的其他对象(比如c2)在绑定speed属性前,则没有该属性,所以直接访问c2.speed会报错:AttributeError: 'Car' object has no attribute 'speed'

通常,如果某个对象需要某个属性、方法,我们可以直接给其绑定属性、方法,但是,给一个实例绑定的属性、方法,对另一个实例是不起作用的,如上面的例子中的speed属性。

为了给所有实例都绑定属性、方法,可以给类Car绑定属性、方法。

现在我们还可以随意地给对象c3绑定一些测试属性:x, y, z:

c3 = Car()
c3.x = 'x'
c3.y = 'y'
c3.z = 'z'
print(c3.x)
print(c3.y)
print(c3.z)

运行结果:

x
y
z

那么问题来了:如果我想要限制实例的属性怎么办?比如,只允许对Car实例添加speedcolor属性。这就需要用到限制对象属性的属性了:__slots__

限制实例属性的属性__slots__

slots:本意是:狭孔、插板上的插槽等。此处表示

只需要在定义类时添加如下代码:__slots__ = 'speed', 'color'即可,只允许对Car实例添加speedcolor属性。Car类定义更新如下:

# 定义一个Car类
class Car(object):
    # 表示只允许对Car实例添加speed和color属性。
    __slots__ = 'speed', 'color'
    pass

同样再次随意绑定其他属性x,测试如下:

# 创建一个Car类对象
c3 = Car()

# 随意绑定一个属性x,并赋值‘x’
c3.x = 'x'

print(c3.x)

运行结果:

Traceback (most recent call last):
  File "F:/python_projects/oop/25Car.py", line 13, in <module>
    c.x = 'x'
AttributeError: 'Car' object has no attribute 'x'

这是由于'x'没有被放到__slots__中,所以不能绑定x属性,试图绑定x将得到AttributeError的错误。

如果,我们不是添加x,而是对Car实例添加speedcolor属性:

# 定义一个Car类
class Car(object):
    __slots__ = 'speed', 'color'
    pass

# 创建Car类的一个实例
c = Car()

# 对Car类对象绑定speed\color属性:
c.speed = '200'
c.color = 'red'

print(c.speed)
print(c.color)

运行结果:

200
red

小结及注意

1.使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。
定义一个大众汽车类DaZhong,继承自Car类,并对DaZhong类的一个实例绑定除speed\color之外的属性,比如:logo属性,代码如下:

# 定义一个Car类
class Car(object):
    __slots__ = 'speed', 'color'
    pass


# 定义一个大众汽车类,继承自Car:
class DaZhong(Car):
    pass

# 创建DaZhong类的一个实例
d = DaZhong()

# 对DaZhong类对象绑定除speed\color之外的属性,比如:logo
d.logo = "DaZhong's logo"

print(d.logo)

运行结果:

DaZhong's logo

可以绑定成功。验证了:__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。除非在子类中也定义__slots__,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots__

2.__slots__限制的是类的实例的属性,且不能和类属性有重名的,否则报错。

# 定义一个Car类
class Car(object):
    __slots__ = 'speed', 'color'
    color = 'white'
    pass

运行结果:

Traceback (most recent call last):
  File "F:/python_projects/oop/25Car.py", line 2, in <module>
    class Car(object):
ValueError: 'color' in __slots__ conflicts with class variable

ValueError: 'color' in __slots__ conflicts with class variable意思是: 值错误:__slots__里面的color属性和类属性color冲突了


更多了解,可关注公众号:人人懂编程


微信公众号:人人懂编程
上一篇 下一篇

猜你喜欢

热点阅读