在 class 方法中引用(仅限模块)全局函数

Reference to (module only) global function within a class method

在 python 中,可以通过名称轻松引用全局方法。

def globalfoo(a):
    print(a)


class myClass:
    def test(self):
        v = globalfoo
        v("hey")

t = myClass()
t.test()

现在 python 也可以 "hide" 一个 (class) 方法,方法是在它前面加上两个下划线。 - 我认为(!)可以对全局函数做同样的事情——创建一个全局函数 module-only。 (类似于 C++,可以决定将函数声明不放在 header 中,因此它仅对当前编译单元可见)。

然后我尝试结合这个:

def __globalfoo(a):
    print(a)


class myClass:
    def test(self):
        v = __globalfoo
        v("hey")

t = myClass()
t.test()

然而这似乎不起作用,抛出一个错误“_myCLass__globalfoo”未定义。那么我将如何使这两件事都起作用:引用一个函数。并从外部范围隐藏函数?
在这种情况下,静态方法是 only/best 解决方案吗?

And I thought(!) one could do the same for global functions - to make a global function module-only.

你错了。为模块级函数使用双下划线名称不会阻止它在其他模块中使用。有人仍然可以做 import yourmodule 然后调用 yourmodule.__globalfoo.

双下划线名称修改行为在 the docs:

中定义

Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.

它纯粹是文本替换,不考虑双下划线名称指的是什么(如果有的话)。它只需要出现在 class 定义中任何地方的任何标识符,看起来像 __blah 并将其更改为 _class__blah。它特定于 class 定义,不会出现在模块级函数中。

最好的办法是在您的函数前添加一个下划线,并说明它不是 public API 的一部分,并且该模块的用户不应依赖它。尝试 "enforce" 此隐私不会获得任何好处。

在python,一般来说,我们不会努力让其他东西无法访问。我们相信其他开发人员不会修改和访问他们不应该修改的内容。无论如何,语言的工作方式几乎不可能让这些东西完全无法访问。

你可以做两件事。模块中内部函数的标准符号是单个下划线——其他程序员应该知道不要干涉这些函数。 Python 甚至在某些方面支持该约定 - 像这样导入时:

from module import *

这不会导入下划线前缀的名称。

另一种方法是在模块末尾 del method。不是很传统,但如果你必须它实现你想做的事情:

def func():
    pass
...
...
del func