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

问题描述:

在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”是不确定的。那么,我将如何使这两件事情有效:对一个函数的引用。并从外部范围隐藏功能?
在这种情况下,静态方法是唯一/最好的解决方案吗?

+0

为什么不只是在类中定义该功能? – Netwave

+0

是的,'@ staticmethod'是一个不错的和干净的解决方案。 – sobolevn

+0

@DanielSanchez,因为函数不需要类*中的任何东西。它也不是特别与班级相结合。对于其他类也可能是一个有用的实用函数。但是,将其公诸于众是非常具体的:它基本上是一个非常成熟的数学方程,它部分解决了。 – paul23

而且我认为(!)人们可以对全局函数做同样的事情 - 只做一个全局函数模块。

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

的双下划线名称重整行为在the docs定义:

形式__spam的任何标识符(至少两个前导下划线,至多一个结尾下划线)的文本上与_classname__spam,其中类名是取代带前导下划线的当前类名称被剥离。只要它在类的定义内发生,就不会考虑标识符的语法位置。

它纯粹是一个文本替换,并且不考虑双下划线名称指的是什么(如果有的话)。它只是在类定义内的任何地方出现类似__blah的任何标识符,并将其更改为_class__blah。它是特定于类定义的,并不适用于模块级功能。

要做的最好的事情是用一个下划线前缀你的函数,并且证明它不是公共API的一部分,模块的用户不应该依赖它。试图“执行”这种隐私没有任何收获。

+0

嗯,让我想知道我是否应该去静态方法或现在不。 (背景我正在写一个轨道力学模拟,其中一部分是解开普勒方程:M = E + ecc * sin(E)代表“E”,这是无法用代数方法完成的,最好的数值方法需要第一个&二阶导数(作为函数指针),所以我提供了这个集合 – paul23

+0

@ paul23:我在答案中加了一点点,你应该做的是用一个下划线命名它,并记录它不是公共API的一部分人们不应该使用它,试图执行这种保护是徒劳的。 – BrenBarn

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

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

from module import * 

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

另一种方式是在模块末尾del method。不是很常规,但如果你必须它达到你想要做的:

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