类中的私有属性
在类中定义一个私有属性如下:
class Person(object): def __init__(self, name): self.__name = name # 定义私有属性 self.__name p = Person('hkey') print(p.__name) # 外部不能直接调用私有属性 执行结果: Traceback (most recent call last): File "E:/learn_python/day26/test6.py", line 11, in <module> print(p.__name) AttributeError: 'Person' object has no attribute '__name'
私有属性的使用场景:
- 隐藏起一个属性,不想让类的外部调用
- 想要保护这个属性,不想让属性随便被改变
- 保护这个属性,不被子类继承
虽然私有属性不能直接从外部调用,但是我们可以通过对象.__dict__ 尝试来获取这个属性试试:
class Person(object): def __init__(self, name): self.__name = name p = Person('hkey') print(p.__dict__) print(p._Person__name) 执行结果: {'_Person__name': 'hkey'} # 执行 p.__dict__ 会直接获取对象的属性和方法 hkey # 在外部可以通过 p._Person__name 来获取类中的私有属性
使用对象通过 _类名__属性名 来获取属性的方式并不推荐,在python中没有强制不允许查看类中私有属性,一切都靠自觉;
将类中的方法当作属性查看修改删除
property 将方法变成属性
一个实例: 写一个类,计算圆的周长和面积
from math import pi class Circle(object): def __init__(self, r): self.__r = r def per(self): # 圆的周长 return 2*pi*self.__r def area(self): # 圆的面积 return pi * self.__r **2 c = Circle(5) print(c.area()) print(c.per())
在上面的代码中,我们要计算圆的周长和面积,都是通过对象.方法名() 去获取的。当我们使用 property 可以通过 对象.属性名 的方式调用函数内的方法,如下:
from math import pi class Circle(object): def __init__(self, r): self.__r = r @property # 通过装饰器的形式,将类中方法调用的方式修改为函数调用的方式 def per(self): return 2*pi*self.__r @property def area(self): return pi * self.__r **2 c = Circle(5) print(c.area) print(c.per)
属性可以重新赋值,但是当使用 property 转换为属性调用的方式后,是不能直接赋值的。
class Person(object): def __init__(self, name): self.__name = name @property # 使用 property 改变类中函数的调用方式 def name(self): return self.__name + ' run.' p = Person('hkey') print(p.name)
setter
当我们要修改对象 p 的 name 属性时,就需要使用 setter
class Person(object): def __init__(self, name): self.__name = name @property def name(self): return self.__name + ' run.' @name.setter # 使用 setter 装饰器 def name(self, new_name): self.__name = new_name p = Person('hkey') print(p.name) p.name = 'xiaofei' # 就可以实现从新赋值 print(p.name)
当使用 setter 时, 我们要明确命名规则:
当使用 setter 时,我们不仅可以赋值,还可以做一些判断
class Person(object): def __init__(self, name): self.__name = name @property def name(self): return self.__name + ' run.' @name.setter def name(self, new_name): if new_name.isalpha(): # new_name 必须是有字母或汉字组成 self.__name = new_name p = Person('hkey') print(p.name) p.name = '123' # 字符串是由数字组成,赋值失败 print(p.name)
deleter
这个组合中最不常用的装饰器:
作用:当要删除类中某个属性的时候使用 deleter 具体使用如下
class Person(object): def __init__(self, name): self.__name = name @property def name(self): return self.__name + ' run.' @name.setter def name(self, new_name): if new_name.isalpha(): # new_name 必须是有字母或汉字组成 self.__name = new_name @name.deleter def name(self): print('