2009-04-10 91 views
3

Python中是否有超级全局(如PHP)?我在整个项目中使用了独立的文件,类和函数中的某些变量,我不想在每个文件中都声明它。Python超全球?

+0

既然你不“声明”任何东西,你的意思是“参考”或“导入”?你能澄清你在做什么导致问题吗? – 2009-04-10 01:57:38

回答

18

在理论上是的,你可以开始喷涌CRUD到__builtin__:

>>> import __builtin__ 
>>> __builtin__.rubbish= 3 
>>> rubbish 
3 

但是,不这样做;这会给你的应用程序编程带来可怕的恶果 - 癌症。

classes and functions and i don't want to have to keep declaring

将它们放入模块中,当需要使用它们时将它们“导入”它们。

I have certain variables i want to use throughout my whole project

如果你必须有不合格的价值,只是把它们放在一个名为类似“mypackage中/ constants.py”则:

from mypackage.constants import * 

如果他们真的是“变量”在您更改他们在应用程序执行期间,你需要开始将它们封装在对象中。

+0

在mypackage.constants中使用`import *`几乎和monkeypatching`__builtin__`一样糟糕 - 它具有破坏命名空间使用的相同效果。正确的建议是你给的:“把它们放在模块中,当你需要使用它们时,”导入“它们。”这不是我们应该灵活处理的一个问题,因为它会伤害我们计划的可读性,灵活性,可预测性和明确性。 – 2011-02-04 13:31:22

+0

@Mike:通常从模块导入nonmodulething`确实是非常不可取的,但对于符号常量的具体情况,我认为这种情况可能是有争议的。在每个用法中输入“mypackage.constants.THINGTYPE_SOMETHING”的完整路径太长。当然,还有其他可能更好的方法,但在这种情况下,潜在的危害会相当小。 – bobince 2011-02-05 11:29:08

4

即使有,你也不应该使用这样的结构EVER。考虑使用borg模式来保存这种东西。

class Config: 
    """ 
    Borg singlton config object 
    """ 
    __we_are_one = {} 
    __myvalue = "" 

    def __init__(self): 
     #implement the borg patter (we are one) 
     self.__dict__ = self.__we_are_one 

    def myvalue(self, value=None): 
     if value: 
      self.__myvalue = value 
     return self.__myvalue 

conf = Config() 
conf.myvalue("Hello") 
conf2 = Config() 
print conf2.myvalue() 

这里我们使用borg模式来创建一个singlton对象。无论您在代码中如何使用此代码,无论您将哪个模块或类实例化为配置,“myvalue”都是相同的。

3

创建空的superglobal.py模块。
在你的文件做:

import superglobal 
superglobal.whatever = loacalWhatever 
other = superglobal.other 
1

这一点不明确你的原因是Python的故意不尽力支持这种事。命名空间是功能,使用它们对您有利。如果您想要在其他文件中定义的内容,请将其导入。这意味着通过阅读您的源代码,您可以找出所有东西来自哪里,并且还使您的代码更易于测试和修改。

4

在多年的实践中,我对python的导入系统感到非常失望:处理正确是很复杂和困难的。另外,我必须在我写的每个模块中保留大量进口,这是皮塔饼。

命名空间是一个非常好的主意,它们是不可或缺的--- php没有适当的命名空间,而且它是一团糟。

在概念上,编写应用程序的一部分在于定义一个合适的词汇表,这些词汇将用于完成所需的工作。然而用传统的方式,正是这些词汇并不容易,因为你必须先导入这个词汇,然后导入它才能获得访问权限。

当命名空间在JavaScript社区就成为关注的焦点,约翰的jQuery的名气Resig的决定,提供全局命名空间的单一$变量是要走的道路:它只会影响全局命名空间最小,并提供方便的一切与jQuery。

同样,我试验了一个全局变量g,它在一定程度上起作用。基本上,您有两种选择:要么有一个启动模块,必须在应用程序中的任何其他模块之前运行,该模块定义g中应该提供哪些内容,以便在需要时准备好。我尝试的另一种方法是使g懒惰,并在需要新名称时与自定义导入进行反应;所以当你第一次需要g.foo.frob(42)时,机制会在幕后尝试类似import foo; g.foo = foo的东西。这样做很难做得正确。

现在,除了标准库和网站包以外,我几乎完全抛弃了导入系统。大多数情况下,我都会为软管库编写包装,因为其中有90%的人无论如何都会有复杂的接口。然后我使用拼写惯例在全局名称空间中发布这些包装,以将碰撞风险降至最低。

我只说这是为了缓解这样一种印象,即修改全局命名空间是一种本质上是邪恶的东西,其他答案似乎是这样。并非如此。什么是邪恶就是轻率地做,或者被语言或包装设计所强迫。

让我补充一句话,因为我几乎肯定会在这里得到一些解释:宗教捍卫命名空间纯度的人所做的所有进口中的99%是错误的。证明?你会在任何需要做三角测量的模块foo.py的起始行中读取,例如from math import sin。现在当你正确地使用import foo并查看该命名空间时,你会发现什么?一些名为foo.sin。但sin不是foo的接口的一部分,它只是一个帮手,它不应该混淆该名称空间---因此,from math import sin as _sin或某些将是正确的。然而,几乎没有人这样做。

我一定会用这些观点引起一些激烈的评论,所以继续。