jbo*_*chi 78
Python中不存在除了从对象内部访问之外无法访问的"私有"实例变量.但是,大多数Python代码都遵循一个约定:前缀为下划线的名称(例如_spam)应被视为API的非公共部分(无论是函数,方法还是数据成员) .它应被视为实施细节,如有更改,恕不另行通知.
由于类私有成员有一个有效的用例(即为了避免名称与子类定义的名称冲突),因此对这种称为名称修改的机制的支持有限.形式为__spam的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为
_classname__spam
,其中classname是当前类名,其中前导下划线被剥离.只要它出现在类的定义中,就可以在不考虑标识符的句法位置的情况下完成这种修改.
所以,例如,
class Test:
def __private_symbol(self):
pass
def normal_symbol(self):
pass
print dir(Test)
Run Code Online (Sandbox Code Playgroud)
将输出:
['_Test__private_symbol',
'__doc__',
'__module__',
'normal_symbol']
Run Code Online (Sandbox Code Playgroud)
__private_symbol
应该被视为一种私人方法,但它仍然可以通过_Test__private_symbol
.
Nou*_*him 34
其他答案提供了技术细节.我想强调一方面Python与C++/Java(我认为你基于你的问题熟悉的语言)之间的哲学差异.
The general attitude in Python (and Perl for that matter) is that the 'privacy' of an attribute is a request to the programmer rather than a barbed wire fence by the compiler/interpreter. The idea is summarised well in this mail and is often referred to as "We're all consenting adults" since it 'assumes' that the programmer is responsible enough to not meddle with the insides. The leading underscores serve as a polite message saying that the attribute is internal.
On the other hand, if you do want to access the internals for some applications (a notable example is documentation generators like pydoc), you're free to do so. Onus is on you as a programmer to know what you're doing and do it properly rather than on the language to force you do to things it's way.
private
Python 中没有任何其他访问保护机制.Python样式指南中记录了一个约定,用于向您的类的用户指示他们不应该访问某些属性.
_single_leading_underscore:弱"内部使用"指标.例如from M import *
,不会导入名称以下划线开头的对象.
single_trailing_underscore_:由约定用于避免与Python关键字冲突,例如 Tkinter.Toplevel(master, class_='ClassName')
__double_leading_underscore:在命名一个类属性时,调用名称修改(在类FooBar中,__ boo变成_FooBar__boo;见下文).
Python不直接支持隐私.程序员需要知道何时从外部修改属性是安全的,但无论如何使用python你可以通过一些小技巧实现私有.现在让我们看看一个人可以将任何私密内容放入其中.
class Person(object): def __priva(self): print "I am Private" def publ(self): print " I am public" def callpriva(self): self.__priva()
现在当我们执行时:
>>> p = Person() >>> p.publ() I am public >>> p.__priva() Traceback (most recent call last): File "", line 1, in p.__priva() AttributeError: 'Person' object has no attribute '__priva' ?#Explanation : You can see here we are not able to fetch that private method directly. >>> p.callpriva() I am Private #?Explanation : Here we can access private method inside class?
那么有人可以访问该变量???
你可以这样做:
>>>p._Person__priva I am Private
哇,实际上如果python得到任何以双下划线开头的变量都是通过在开头添加一个下划线和类名来"翻译"的:
注意:如果您不希望此名称发生更改,但您仍希望发送其他对象的信号以避开,则可以使用带有初始下划线的单个初始下划线名称不会导入带星号的导入(来自模块导入*)
示例:
#test.py def hello(): print "hello" def _hello(): print "Hello private" #----------------------
#test2.py from test import * print hello() print _hello()
输出 - >
hello Traceback (most recent call last): File "", line 1, in NameError: name '_hello' is not defined
现在我们将手动调用_hello.
#test2.py from test import _hello , hello print hello() print _hello()
输出 - >
hello hello private
最后:Python并没有真正具有同等的隐私支持,尽管单个和双重初始下划线在某种程度上确实为您提供了两个级别的隐私
归档时间: |
|
查看次数: |
46088 次 |
最近记录: |