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

时间:2015-11-07 21:52:20

标签: python function-pointers encapsulation

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

def globalfoo(a):
    print(a)


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

t = myClass()
t.test()

现在在python中也可以隐藏"一个(类)方法,前缀为两个下划线。 - 我认为(!)可以为全局函数做同样的事情 - 只创建一个全局函数模块。 (类似于C ++,其中可以决定将函数声明放在标题中,以便它只对当前编译单元可见。)

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

def __globalfoo(a):
    print(a)


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

t = myClass()
t.test()

然而,这似乎不起作用,引发错误" _myCLass__globalfoo"未定义。那么我将如何使两件事都有效:引用一个函数。并将功能隐藏在外部范围内?
在这种情况下,静态方法是唯一/最佳解决方案吗?

2 个答案:

答案 0 :(得分:3)

  

我认为(!)可以为全局函数做同样的事情 - 只创建一个全局函数模块。

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

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

  

__spam形式的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为_classname__spam,其中classname是当前类名,前导下划线被剥离。只要它出现在类的定义中,就可以在不考虑标识符的句法位置的情况下完成这种修改。

纯粹是文本替换,不考虑双下划线名称所指的内容(如果有的话)。它只需要在类定义中的任何位置出现类似__blah的标识符,并将其更改为_class__blah。它特定于类定义,不适用于模块级函数。

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

答案 1 :(得分:0)

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

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

from module import *

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

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

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