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

像大多数语言一样,Python具有 私有元素的概念: 私人 函数,这些函数不能被调用 在模块外

然而,如果我定义两个文件:

#a.py
__num=1

and:

#b.py
import a
print a.__num

当我运行b.py时,它输出1而不给出任何异常。是diveintopython错了,还是我误解了什么?是否有方法将模块的函数定义为私有?


当前回答

In Python, "privacy" depends on "consenting adults'" levels of agreement - you can't force it (any more than you can in real life;-). A single leading underscore means you're not supposed to access it "from the outside" -- two leading underscores (w/o trailing underscores) carry the message even more forcefully... but, in the end, it still depends on social convention and consensus: Python's introspection is forceful enough that you can't handcuff every other programmer in the world to respect your wishes.

((顺便说一下,虽然这是一个严格保密的秘密,但对于c++来说也是如此:在大多数编译器中,在#包括你的.h文件之前,一个简单的#define private public line就可以让狡猾的编码器对你的“隐私”进行散列…!-))

其他回答

In Python, "privacy" depends on "consenting adults'" levels of agreement - you can't force it (any more than you can in real life;-). A single leading underscore means you're not supposed to access it "from the outside" -- two leading underscores (w/o trailing underscores) carry the message even more forcefully... but, in the end, it still depends on social convention and consensus: Python's introspection is forceful enough that you can't handcuff every other programmer in the world to respect your wishes.

((顺便说一下,虽然这是一个严格保密的秘密,但对于c++来说也是如此:在大多数编译器中,在#包括你的.h文件之前,一个简单的#define private public line就可以让狡猾的编码器对你的“隐私”进行散列…!-))

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

下面是一个私有类函数的例子:

class foo():
    def bar(self): pass
    def __bar(self): pass

f = foo()
f.bar()   # this call succeeds
f.__bar() # this call fails

嵌入闭包或函数是一种方法。这在JS中很常见,但对于非浏览器平台或浏览器worker来说不是必需的。

在Python中,这似乎有点奇怪,但如果确实需要隐藏一些东西,那可能是一种方法。更重要的是,使用python API并将需要隐藏在C(或其他语言)中的内容可能是最好的方法。如果做不到这一点,我会把代码放在一个函数中,调用它,让它返回你想要导出的项。

Python有三种模式via。当导入一个模块时,只有public模式是可访问的。因此private和protected模块不能从模块外部调用,即当它被导入时。

你可以添加一个内部函数:

def public(self, args):
   def private(self.root, data):
       if (self.root != None):
          pass #do something with data

如果你真的需要那种程度的隐私的话。