引用类方法中的(仅模块)全局函数

最后发布: 2015-11-07 21:52:19


问题

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

def globalfoo(a):
    print(a)


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

t = myClass()
t.test()

现在,在python中,还可以通过在其前面加上两个下划线来“隐藏”(类)方法。 -我以为(!)可以对全局函数做同样的事情-仅使全局函数成为模块。 (类似于C ++,在C ++中,可以决定不将函数声明放在标头中,因此仅对当前编译单元可见)。

然后,我尝试将其结合起来:

def __globalfoo(a):
    print(a)


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

t = myClass()
t.test()

但是,这似乎不起作用,将引发错误,指出“ _myCLass__globalfoo”未定义。 因此,我将如何使这两种方法都起作用:引用一个函数。 并从外部范围隐藏功能?
在这种情况下,静态方法是唯一/最佳解决方案吗?

python function-pointers encapsulation
回答

我认为(!)可以对全局函数做同样的事情-将全局函数制作为仅模块函数。

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

双下划线名称修饰行为是在docs中定义

形式为__spam任何标识符(至少两个前导下划线,至多一个下划线)在文本上被_classname__spam替换,其中classname是当前的类名,其中前导下划线被去除。 只要不存在标识符的语法位置,就可以进行这种改写,只要它出现在类的定义内即可。

它纯粹是文本替换,不考虑双下划线名称所指的含义(如果有的话)。 它只需要出现在类定义内任何看起来像__blah并将其更改为_class__blah 它特定于类定义,并且对于模块级功能不会发生。

最好的办法是在函数前加一个下划线,并说明该函数不是公共API的一部分,并且该模块的用户不应依赖该函数。 尝试“执行”此隐私没有任何好处。


回答

通常,在python中,我们不会尽力使其他东西无法访问。 我们相信其他开发人员不要修改和访问他们不应做的事情。 无论如何,语言的工作方式几乎不可能使这些东西完全不可访问。

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

from module import *

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

另一种del method是在模块末尾使用del method 这不是很常规,但是如果您必须达到目标,则可以:

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