参考网址
https://blog.csdn.net/weixin_35688430/article/details/108081059
-
"__init__()" 方法不能有返回值,也就是只能是return None
-
为'类'添加装饰器(本示例中,给'类'动态增加一个属性)
def add_name(name):
def wrapper(cls):
cls.name = name
return cls
return wrapper
@add_name('JimGreen')
class Person(object):
age = 20
p = Person()
print(p.name) # JimGreen
私有属性: 以 '双下划綫' 开头
__age
- demo 演示
class Person:
def __init__(self, name, age=18):
self.name = name
self.__age = age
def growup(self, i=1):
if i > 0 and i < 150: # 控制逻辑
self.__age += 1
p1 = Person('tom')
p1.growup(20) # 正常的范围
print(p1.__age) # 访问不到
- 如果访问'私有属性',通过自定义内部方法访问('熟人'走后门)
class Person:
def __init__(self, name, age=18):
self.name = name
self.__age = age
def growup(self, i=1):
if i > 0 and i < 150: # 控制逻辑
self.__age += 1
def getage(self):
return self.__age
print(Person('tom').getage()) # 18
- 在外部强行访问'私有变量'也是可以的(不推荐)
class Person:
def __init__(self, name, age=18):
self.name = name
self.__age = age
def growup(self, i=1):
if i > 0 and i < 150: # 控制逻辑
self.__age += 1
def getage(self):
return self.__age
p1 = Person('tom')
p1.growup(20) # 正常的范围
# print(p1.__age) # 访问不到
p1.__age = 28 # 设置实例属性
print(p1.__age) # 28
print(p1.getage()) # 19 # 为什么年龄不一样?__age没有覆盖吗?
print(p1.__dict__) # {'name': 'tom', '_Person__age': 19, '__age': 28}
print(p1._Person__age) # 19
p1._Person__age = 15 # 修改私有属性的值
print(p1.getage()) # 15
'''
- 秘密都在 __dict__ 中,里面是 {’__age’: 28, ‘_Person__age’: 38, ‘name’: ‘tom’}
- 私有变量的本质:类定义的时候,如果声明一个实例变量的时候,使用双下划线,Python解释器会将其改名,转换名称为 "_类名__变量名" 的名称,使用原来的名字访问不到
'''
保护变量: 以'单下划线'开头
_age
class Person:
def __init__(self, name, age=18):
self.name = name
self._age = age
p1 = Person('tom')
print(p1._age) # 18
print(p1.__dict__) # {'name': 'tom', '_age': 18}
12345678
'''
- 可以看出,这个_age属性根本就没有改变名称,和普通的属性一样,解释器不做任何特殊处理
- 这只是开发者共同的约定,看见这种变量,就如同私有变量,不要直接使用
'''
私有方法:参考私有属性,类似
class Person:
def __init__(self, name, age=18):
self.name = name
self._age = age
def _getname(self): # 没改名
return self.name
def __getage(self): # 已改名,_Person__getage
return self._age
tom = Person('tom')
print(tom._getname()) # tom
# print(tom.__getage()) # AttributeError
print(tom.__dict__) # {'name': 'tom', '_age': 18}
print(tom.__class__.__dict__)
print(tom._Person__getage()) # 18
'''
- 单下划线的方法只是开发者之间的约定,解释器不做任何改变
- 双下划线的方法,是私有方法,解释器会改名,改名策略和私有变量相同, _类名__方法名
- 方法变量都在类的 __dict__ 中可以找到。
'''
小结
- 在Python中使用 _单下划线 或者 __ 双下划线来标识一个成员被保护或者被私有化隐藏起来
- 但是,不管使用什么样的访问控制,都不能真正的阻止用户修改类的成员。Python中没有绝对的安全的保护成员 或者私有成员
- 因此,前导的下划线只是一种警告或者提醒,遵守这个约定。除非真有必要,不要修改或者使用保护成员或者私有成员,更不要修改它们。