Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python中定义私有模块函数_Python_Function_Module_Private - Fatal编程技术网

在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(

根据:

与大多数语言一样,Python具有 私人要素的概念:

  • 私人的 无法从调用的函数 模块外
但是,如果我定义两个文件:

#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广泛贡献的高度权威性