私有化属性
Python 并没有真正的私有化支持,但是可以使用下划线完成伪私有化的效果。
类属性和实例属性遵循相同的规则。
x
公有属性
- 类内部访问
- 子类内部访问
- 模块内其他位置访问
- 类访问
- 实例访问
- 跨模块访问
- import 形式导入
- from 模块 import * 形式导入
class Animal:
x = 10
def test(self):
print(Animal.x)
print(self.x)
class Dog(Animal):
def test2(self):
print(Dog.x)
print(self.x)
a = Animal()
a.test()
d = Dog()
d.test2()
print(Animal.x)
_y
受保护属性
- 类内部访问
- 子类内部访问
- 模块内其他位置访问
- 类访问
- 实例访问
- 跨模块访问
- import 形式导入
- from 模块 import * 形式导入, 有__all__指明对应变量
class Animal:
_x = 10
def test(self):
print(Animal._x)
print(self._x)
class Dog(Animal):
def test2(self):
print(Dog._x)
print(self._x)
a = Animal()
a.test()
d = Dog()
d.test2()
print(Animal._x)
__all__ = ['_a']
_a = 666
__z
私有属性
- 类内部访问
- 跨模块访问
- import 形式导入
- from 模块 import * 形式导入, 有__all__指明对应变量
class Animal:
__x = 10
def test(self):
print(Animal.__x)
print(self.__x)
a = Animal()
a.test()
__all__ = ['__a']
_a = 666
私有属性的实现机制:名字重整(Name Mangling), 重改__x为另外一个名称,如_类名__x
目的:防止外界直接访问,防止被子类同名称属性覆盖
class Person:
# 创建好一个实例对象之后,会自动的调用这个方法,来初始化这个对象
def __init__(self):
self.__age = 18
def setAge(self, value):
if isinstance(value, int) and 0 < value < 200:
self.__age = value
else:
print('数据有问题')
def getAge(self):
return self.__age
p1 = Person()
p1.setAge(20)
print(p1.getAge())
补充
xx_
用于区分关键字
__xx__
系统内置
只读属性
一个属性(一般指实例属性),只能读取,不能写入
有些属性,只限于内部根据不同场景进行修改,而对外界来说,不能修改,只能读取
方式1
全部隐藏,私有化,既不能读,也不能写。
部分公开,公开读的操作。
私有化:通过属性前置双下划线实现。
部分公开:通过公开的方法。
class Person:
# 创建好一个实例对象之后,会自动的调用这个方法,来初始化这个对象
def __init__(self):
self.__age = 18
def getAge(self):
return self.__age
p1 = Person()
print(p1.getAge())
优化:
property
将一些属性的操作方法关联到某一个属性中
class Person(object):
# 创建好一个实例对象之后,会自动的调用这个方法,来初始化这个对象
def __init__(self):
self.__age = 18
# 主要作用就是,可以以使用属性的方式,来使用这个方法
@property
def age(self):
return self.__age
p1 = Person()
print(p1.age)
property
概念补充:
经典类:没有继承(object)
新式类:继承(object)
python3 默认新式类,会隐式的继承object。
建议使用新式类。
class Person:
pass
print(Person.__bases__)
(<class ‘object’>,)
class Person(object):
pass
print(Person.__bases__)
(<class ‘object’>,)
class Person(object):
def __init__(self):
self.__age = 18
def get_age(self):
print('---, get')
return self.__age
def set_age(self, value):
print('---, set')
self.__age = value
age = property(get_age, set_age)
p = Person()
print(p.age)
p.age = 90
print(p.age)
—, get
18
—, set
—, get
90
class Person(object):
def __init__(self):
self.__age = 18
@ property
def age(self):
print('---, get')
return self.__age
@age.setter
def age(self, value):
print('---, set')
self.__age = value
p = Person()
print(p.age)
p.age = 90
print(p.age)
—, get
18
—, set
—, get
90
方式2
class Person(object):
# 当我们通过 实例.属性 = 值,给一个实例增加一个属性,或者修改一个属性值的时候,都会调用这个方法
# 在这个方法内部,才会真正的把这个属性以及对应的数据,给存储到__dict__字典里面
def __setattr__(self, key, value):
print(key, value)
# 判定 key 是否是我们要设置的只读属性
if key == 'age' and key in self.__dict__.keys():
print('这个属性是只读属性')
else:
# 如果不是只读属性的名称,添加到这个实例里面
self.__dict__[key] = value
p1 = Person()
p1.age = 18
print(p1.age)
p1.age = 999
print(p1.age)
print(p1.__dict__)
age 18
18
age 999
这个属性是只读属性
18
{‘age’: 18}
内置特殊属性
类属性:
class Person(object):
"""
文档说明
"""
age = 19
def __init__(self):
self.name = 'sz'
def run(self):
print('run')
# 类的属性
print(Person.__dict__)
# 类的所有父类构成元组
print(Person.__bases__)
# 类的文档字符串
print(Person.__doc__)
# 类名
print(Person.__name__)
# 类定义所在的模块
print(Person.__module__)
# 实例对应的类
p = Person()
print(p.__class__)
{‘module’: ‘main’, ‘doc’: '\n 文档说明\n ', ‘age’: 19, ‘init’: <function Person.init at 0x041F0738>, ‘run’: <function Person.run at 0x041F0780>, ‘dict’: <attribute ‘dict’ of ‘Person’ objects>, ‘weakref’: <attribute ‘weakref’ of ‘Person’ objects>}
(<class ‘object’>,)
文档说明
Person
main
<class ‘main.Person’>