在python中定义私有模块函数
根据: 与大多数语言一样,Python具有 私人要素的概念:在python中定义私有模块函数,python,function,module,private,Python,Function,Module,Private,根据: 与大多数语言一样,Python具有 私人要素的概念: 私人的 无法从调用的函数 模块外 但是,如果我定义两个文件: #a.py __num=1 以及: 当我运行b.py时,它打印出1,没有给出任何异常。DiveIntophon错了,还是我误解了什么?有什么方法可以将模块的函数定义为私有的吗?Python允许使用带有双下划线前缀的私有类成员。这种技术在模块级不起作用,所以我认为这是深入Python的一个错误 下面是私有类函数的示例: class foo(): def bar(
- 私人的 无法从调用的函数 模块外
#a.py
__num=1
以及:
当我运行b.py
时,它打印出1
,没有给出任何异常。DiveIntophon错了,还是我误解了什么?有什么方法可以将模块的函数定义为私有的吗?Python允许使用带有双下划线前缀的私有类成员。这种技术在模块级不起作用,所以我认为这是深入Python的一个错误
下面是私有类函数的示例:
class foo():
def bar(self): pass
def __bar(self): pass
f = foo()
f.bar() # this call succeeds
f.__bar() # this call fails
类列兵和模块列兵之间可能存在混淆 专用模块以一个下划线开始 使用import命令的
from import*
形式时,不会复制这样的元素;但是,如果使用import
语法()只需从问题示例的a..\u num中删除一个下划线,它就不会显示在使用import*语法导入a.py的模块中 一堂私人课以两个下划线开始(又名dunder,即分数下的d-ouble)
这样一个变量的名称被“损坏”以包括类名等。
仍然可以通过损坏的名称在类逻辑之外访问它。
尽管名称篡改可以作为一种温和的防止未经授权访问的设备,但其主要目的是防止可能与祖先类的类成员发生名称冲突。 参见AlexMartelli滑稽但准确地提到同意的成年人,因为他描述了在这些变量方面使用的惯例
>>> 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
>>>
>>类Foo(对象):
... __巴=99
... def打印栏(自身):
... 打印(自动打印栏)
...
>>>myFoo=Foo()
>>>myFoo.uu bar#直接尝试禁止进入
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
AttributeError:“Foo”对象没有属性“\uu bar”
>>>myFoo.PrintBar()#类本身当然可以访问它
99
>>>dir(Foo)#还可以看到吗
['PrintBar'、'uFoo'uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu__
格式为“\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,
"减少","减少","增加","报告","设置属性","大小","结构"__
“,”子类钩子“,”子类钩子“,”子类钩子“,”子类钩子“,”
>>>myFoo.Foo_o_o_35;酒吧35;用它被弄坏的名字去吧!(但我不应该!!!)
99
>>>
在Python中,“隐私”取决于“成年人同意”的协议级别——你不能强迫它(就像在现实生活中一样;-)。一个前导下划线意味着你不应该“从外部”访问它--两个前导下划线(不带尾随下划线)更有力地传递信息。。。但是,归根结底,这仍然取决于社会惯例和共识:Python的内省足够强大,以至于你无法束缚世界上所有其他程序员尊重你的意愿
(顺便说一句,虽然这是一个秘密,但对C++来说也是一样:对于大多数编译器来说,在
之前只需一行简单的#定义private public
#就可以包含压缩你的.h
文件,这是狡猾的程序员对你的“隐私”进行散列所需要的一切…)这个问题没有完全回答,由于模块隐私并非纯粹的常规,并且由于使用导入可能识别模块隐私,也可能不识别模块隐私,这取决于模块隐私的使用方式
如果在模块中定义私有名称,则这些名称将导入到使用语法“import module_name”的任何脚本中。因此,假设您在示例中正确地定义了a.py中的模块private,_num,如下所示
#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有三种模式:via.,private,public和protected。在导入模块时,只能访问public模式。因此,在导入模块时,不能从模块外部调用private和protected模块。这是一个古老的问题,但模块私有(一个下划线)和类私有(两个下划线)标准文档中现在介绍了损坏的变量:
»»嵌入闭包或函数是一种方法。这在JS中很常见,但对于非浏览器平台或浏览器工作人员不是必需的
在Python中,这似乎有点奇怪,但是如果真的需要隐藏某些东西,那么可能就是这样。更重要的是,使用pythonapi并将需要隐藏的内容保留在C(或其他语言)中可能是最好的方法。如果失败,我会将代码放入函数中,调用该函数并让它返回要导出的项。您可以添加一个内部函数:
def public(self, args):
def private(self.root, data):
if (self.root != None):
pass #do something with data
如果你真的需要那种程度的隐私,可以这样做。方法:(我不确定这是否正是你想要的)
打印三次.py
def private(method):
def methodist(string):
if __name__ == "__main__":
method(string)
return methodist
@private
def private_print3(string):
print(string * 3)
private_print3("Hello ") # output: Hello Hello Hello
from print_thrice import private_print3
private_print3("Hello From Another File? ") # no output
其他_文件.py
def private(method):
def methodist(string):
if __name__ == "__main__":
method(string)
return methodist
@private
def private_print3(string):
print(string * 3)
private_print3("Hello ") # output: Hello Hello Hello
from print_thrice import private_print3
private_print3("Hello From Another File? ") # no output
这可能不是一个完美的解决方案,因为您仍然可以“看到”和/或“调用”该方法。无论如何,它不会执行。好吧,直到。但是,他们为什么不强制执行模块级的\uuuuu private\u函数
?我遇到了这个问题,也因此出错了。谢谢你对我说的客气话@Terrabits,但我很高兴在所有的“Python”方面都排在Alex之后(远远落后!)。此外,他的回答通常更加简洁和幽默,同时保持了Alex广泛贡献的高度权威性