Python面向对象编程中如何实现访问控制?
写了一篇关于 Python 访问控制的文章,请各位大佬鉴定一下。
https://juejin.im/post/5ac18d08f265da237b223d1a
Python面向对象编程中如何实现访问控制?
学 py 的时候看过这段,严格来说 py 是没有私有的,通过下划线其实是提醒后来人谨慎使用该变量。
在Python里实现访问控制,主要靠命名约定和属性装饰器。Python没有Java那种严格的private、protected关键字,但有一套大家遵守的规则。
1. 单下划线 _:约定上的“保护”成员
加个单下划线开头,比如 _protected_var。这只是个约定,告诉其他程序员:“这是内部用的,别直接从外面乱动”。但解释器不会阻止你访问。
class MyClass:
def __init__(self):
self.public = "随便访问"
self._protected = "建议别直接动我"
obj = MyClass()
print(obj.public) # 可以
print(obj._protected) # 也可以,但不太讲究
2. 双下划线 __:名称改写(Name Mangling)
用双下划线开头,比如 __private_var。Python解释器会把这个属性名改成 _类名__变量名 的形式。这算是某种程度的“私有化”,主要为了防止子类意外重写父类属性。
class MyClass:
def __init__(self):
self.__private = "我真的不想被直接改"
def get_private(self):
return self.__private
obj = MyClass()
# print(obj.__private) # 直接这么访问会报错:AttributeError
print(obj.get_private()) # 通过公有方法访问,可以
print(obj._MyClass__private) # 知道改名规则后硬要访问,也行,但非常不推荐
3. 属性装饰器 @property:控制访问和修改
这是最Pythonic、最常用的方式。用 @property 把一个方法变成“属性”来读,用 @属性名.setter 来控制写操作,用 @属性名.deleter 控制删除。你可以在这些方法里加任何检查逻辑。
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
@property
def age(self):
"""获取年龄"""
return self._age
@age.setter
def age(self, value):
"""设置年龄,加个合法性检查"""
if not isinstance(value, int):
raise TypeError("年龄得是整数")
if value < 0 or value > 150:
raise ValueError("年龄得现实点")
self._age = value
@age.deleter
def age(self):
"""不让删年龄属性"""
raise AttributeError("年龄这属性可不能删")
p = Person("小明", 25)
print(p.age) # 像属性一样读,实际调用的是 getter 方法
p.age = 30 # 像属性一样写,实际调用的是 setter 方法
# p.age = -5 # 会触发 ValueError
# del p.age # 会触发 AttributeError
总结一下:
- 想暗示“内部使用”:用单下划线
_。 - 想避免子类属性冲突:用双下划线
__触发名称改写。 - 想精细控制属性的读、写、删行为,并加入逻辑:用
@property装饰器。
核心建议: 多用 @property,它是Python实现封装和访问控制的首选工具。
楼主要想搞个大新闻,还是找点有深度的主题吧!这东西任何一本入门书都有讲解
讲 py3 源码才能在 v 站立足 
标题赞一个
谢谢楼主不辞辛苦跑来告诉大家母鸡是会下蛋的。
只是哲学不同,我们都认为自己是成年人。
感谢 + 没有帮助(
这篇真的有点水了… python 不了解这个特性可以说是完全不会 python 吧…
真正访问控制应该是 吧
快出去走道里看看 看到墙上有火警报警按钮没,会不会误触?非要按能不能按下去?但是你应不应该按?
基础文章,还不错 ; ) 可以看看描述符之类
只是哲学不同,我们都认为自己是成年人,这句话什么意思?
写得可以,之前一直把 python 当脚本来写的,面向对象没用过
everything is available at runtime
正确的访问控制应该使用 getattr setattr
自定义的方法或变量在任何时候都不应该使用 foo 的形式。js 社区前短时间好像在争执 Array.prototype.flatten 的方法问题,因为和有个库定义了 flatten,js 如果加入这个的话会冲突。所以有人提议我们用 smoosh (笑)
Python 就没有这个问题,只要大家老老实实把魔术方法保留给 Python 语言。
和 9 楼一个意思。
配图用个 C++//
。。。。。。。。。。。任何一本 python 入门数都会讲的东西
如果对这个都不了解换我我可能直接拒了
1、_xxx 不能用于’ from module import *’ 以单下划线开头的表示的是 protected 类型的变量。即保护类型只能允许其本身与子类进行访问。
2、__xxx 双下划线的表示的是私有类型的变量。只能是允许这个类本身进行访问了。连子类也不可以
“”“是一种约定的规范,而不是语言层面真的实现了访问控制…”"" lz 搞笑吗
这句话有什么问题吗?
这怕是不能谈笑风生吧
水到不行

