在python中定义私有模块函数

根据http://www.faqs.org/docs/diveintopython/fileinfo_private.html :

像大多数语言一样,Python具有私有元素的概念:

  • 私有函数,不能从模块外调用

但是,如果我定义了两个文件:

#a.py __num=1 

和:

 #b.py import a print a.__num 

当我运行b.py它打印出1没有任何例外。 diveintopython错了,还是我误解了一些东西? 有没有办法一个模块的function定义为私人?

在Python中,“隐私”取决于“同意成人”的协议级别 – 你不能强迫它(比现实生活中的任何更多);-)。 一个主要的下划线意味着你不应该从外面访问它 – 两个主要的下划线(没有尾随的下划线)更强有力地传达了这个信息……但最终还是取决于社交公约和共识:Python的反思是足够强大的,你不能手铐在世界上的其他程序员尊重你的愿望。

((顺便说一句,虽然这是一个密切的秘密,对于C ++来说也是一样:对于大多数编译器来说,在#include你的.h文件之前需要一个简单的#define private public行,这对于狡猾的编码人员来说,隐私”…!-))

私生子私生子之间可能会混淆。

一个私人模块一个下划线开始
使用import命令的from <module_name> import *forms时,不会复制这样的元素; 但是,如果使用import <moudule_name>语法,则会导入它( 请参阅Ben Wilhelm的答案 )
只需从问题示例的a .__ num中删除一个下划线,并且不会在使用from a import *语法导入a.py的模块中显示。

一个class级私人开始有两个下划线 (又名dunder,即双重低分)
这样一个variables的名字“mangled”包含了类名等
它仍然可以在类逻辑之外通过错位的名字来访问。
虽然这个名字可以作为防止未授权访问的温和预防手段,但其主要目的是防止与祖先类的成员名称冲突。 看到亚历克斯·马尔泰利(Alex Martelli)对成年人同意的有趣而准确的提及,他描述了这些variables所使用的惯例。

 >>> class Foo(object): ... __bar = 99 ... def PrintBar(self): ... print(self.__bar) ... >>> myFoo = Foo() >>> myFoo.__bar #direct attempt no go Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Foo' object has no attribute '__bar' >>> myFoo.PrintBar() # the class itself of course can access it 99 >>> dir(Foo) # yet can see it ['PrintBar', '_Foo__bar', '__class__', '__delattr__', '__dict__', '__doc__', '__ format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__ ', '__subclasshook__', '__weakref__'] >>> myFoo._Foo__bar #and get to it by its mangled name ! (but I shouldn't!!!) 99 >>> 

这个问题没有得到充分的回答,因为模块的隐私并不是纯粹的传统,因为使用导入可能会或可能不会识别模块的隐私,这取决于它的使用方式。

如果在模块中定义专用名称,则这些名称被导入到使用语法“import module_name”的任何脚本中。 因此,假设你已经正确地在你的例子中定义了模块private,_num,在a.py中,就像这样..

 #a.py _num=1 

..你可以通过模块名称符号在b.py中访问它:

 #b.py import a ... foo = a._num # 1 

要仅从a.py中导入非私属,您必须使用from语法:

 #b.py from a import * ... foo = _num # throws NameError: name '_num' is not defined 

但是,为了清晰起见,从模块中导入名称时最好是明确的,而不是用“*”来导入它们:

 #b.py from a import name1 from a import name2 ... 

Python允许使用双下划线前缀的私有成员。 这种技术在模块级别不起作用,所以我认为这是Dive Into Python中的一个错误。

这是一个私人类function的例子:

 class foo(): def bar(self): pass def __bar(self): pass f = foo() f.bar() # this call succeeds f.__bar() # this call fails 

这是一个古老的问题,但是标准文档中现在涵盖了模块私有(一个下划线)和类私有(两个下划线)

Python教程 » 类 » 私有variables

Python有三种模式,通过。,private,public和protected。在导入一个模块的时候,只有公共模式是可以访问的。所以私有模块和被保护模块不能从模块外调用,也就是导入时。