使Python函数中的所有变量都是全局的

use*_*422 18 python function global-variables

是否有一种简单的方法可以使函数中的所有变量全局化?

我在一个函数中有20个奇数变量并且逐个命名它们并不是很好的代码...反正我:)

mha*_*wke 50

警告:不要在家里试试这个,你可能会把它烧掉.

在正常的日常编程过程中没有正当理由做以下事情.请查看此问题的其他答案,以获得更实际的替代方案.

我几乎无法想象你为什么要这样做,但这是一种方法:

def f(a, b, c):
    d = 123
    e = 'crazy, but possible'
    globals().update(locals())

def g():
    print a, b, c, d ,e

>>> globals()
{'g': <function g at 0x875230>, 'f': <function f at 0x8751b8>, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', '__doc__': None}

>>> g()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in g
NameError: global name 'a' is not defined

>>> f(10, 20, 'blah')
>>> g()
10 20 blah 123 crazy, but possible

>>> globals()
{'a': 10, 'c': 'blah', 'b': 20, 'e': 'crazy, but possible', 'd': 123, 'g': <function g at 0x875230>, 'f': <function f at 0x8751b8>, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', '__doc__': None}
Run Code Online (Sandbox Code Playgroud)

  • @Ned Batchelder:尽管很糟糕,但这回答了OP的问题.我同意你的评论,但另一方面,你的答案否认它甚至可能 - 显然它实际上是可能的.他要求烧毁他的房子; 你告诉他这是不可能的......我希望他不会问你怎么灭火:) (26认同)
  • @Ned Batchelder:不,正如我所说,我同意你的评论.我不同意你的答案部分说明没有办法做到这一点,所以我把你的答案贴在你的后面,表明它确实可行.我(或你)是谁判断问题的目的或OP的经验水平?当然可能没有正当理由这样做,这太过分了,但也许OP只是好奇.无论如何,我已经用警告更新了我的答案. (15认同)
  • @mhawke:我希望你不要认真地相信你正在通过逐字回答他的问题来帮助OP,而不是指出他正确的答案.如果一个同事问你这个问题,你会这样回答然后回到自己的工作吗?或者你会坚持帮他写好代码吗? (4认同)
  • 虽然OP肯定不应该这样做,但是当我看到这个问题的标题时,它完全回答了我的想法. (4认同)
  • 不要看我搞笑,但我可以想象这个技巧可能有用的地方.例如,在科学计算中,如果您只想在快速数据修改脚本中重用一个操作(因此将其抛入函数中),您只需使用一次.随着NumPy和SciPy围绕Python被用于许多非软件的东西.现在,我从来没有这样做,但我不能说我们应该假装它不能做,以免一些新手出错.我认为两者都没有显示它是如何完成的,而且通常不应该这样做. (4认同)
  • gh,你们真是太该死了,独身,自以为是!长一双!这不像python甚至用其他可能会在屁股上咬你的随机废话弄乱了locals()一样。谢谢,这是一个很好的答案,而且非常有用。在投入一些要点来否决所有拒绝该问题或完美答案的答案。 (4认同)
  • 我认为在"正常"代码中,这确实不是一个好主意.如果你正在做一些疯狂的元编程或搞乱解释器内部,那么它可能是有用的,但不适用于一般的应用程序代码:( (2认同)
  • 有时当你编写包含函数的长代码的导频时,在函数内部会发生一些错误,如果他知道函数内部的变量的实际值是什么,如果他们是本地的,他就不知道这些错误会更好地找出这些错误. (2认同)

Ned*_*der 13

没有办法将它们全部声明为全局,你真的不想这样做.这20个变量可能应该变成具有20个属性的对象.

  • -1,"回答"一个"不要那样做"的问题不是答案.回答"你可以,但不应该,所以出于教育目的,学习Python如何工作,这说明了如何,现在这就是你应该做的事情",这是一个答案. (8认同)
  • @Ben.问题是,"有一个简单的方法......"答案是,"不." (6认同)
  • 这不是答案.十个upvotes不能成为一个答案.请改用问题评论. (4认同)
  • 究竟是一个对象是什么.或者关闭,也许. (3认同)
  • 这可能是一个很好的建议,但良好的意图不会使"无法"的陈述正确.这应该编辑. (3认同)

sni*_*im2 13

执行此操作的pythonic方法是将变量保持在局部范围内(即在每个函数中定义它们)并将它们作为参数/返回值在函数之间传递; 或者将变量保存为在该类中创建"函数"方法的对象或类的属性.无论哪种方式都可以,但global关键字专门设计用于让您以您描述的方式使用它.全局变量不仅仅是"坏的风格",而且它们使代码很难维护,因为需要在每个函数中检查变量需要遵守的任何不变量.

这是一个好样式的例子(带有函数):

def quads(a, b, c):
    x1 = (-1.0 * b + math.sqrt(b * b - 4.0 * a * c)) / (2.0 * a)
    x2 = (-1.0 * b - math.sqrt(b * b - 4.0 * a * c)) / (2.0 * a)
    return x1, x2

def pretty(a, b, c, x1, x2):
    eqn = "%fx^2 + %fx + %c" % (a, b, c)
    print "The first solution to the equation %s is: %f" % (eqn, x1)
    print "The second solution to the equation %s is: %f" % (eqn, x2)
    return

def main():
    a = 100
    b = 200
    c = 300
    x1, x2 = quads(a, b, c)
    pretty(a, b, c, x1, x2)
    return

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

这是一个好样式的例子(使用OOP):

class Quadratic(object):

    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c
        self.x1 = None 
        self.x2 = None 
        self.solve() # Set x1 and x2 to correct values
        # To maintain the invariant between a, b, c and x1, x1
        # we should override __setattr__ or use descriptors or
        # properties so that self.solve() is called every time
        # a, b, or c are updated.
        return

    def solve(self):
        self.x1 = (-1.0 * self.b +
                   math.sqrt(self.b * self.b - 4.0 * self.a * self.c)) / (2.0 * self.a)
        self.x2 = (-1.0 * self.b - 
                   math.sqrt(self.b * self.b - 4.0 * self.a * self.c)) / 2.0 * self.a
        return 

    def pretty(self):
        eqn = "%fx^2 + %fx + %c" % (self.a, self.b, self.c)
        print "The first solution to the equation %s is: %f" % (eqn, self.x1)
        print "The second solution to the equation %s is: %f" % (eqn, self.x2)
        return

def main():
    quad = Quadratic(100, 200, 300)
    quad.pretty()
    return

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)


Bra*_*des 6

最简单的解决方案是只有一个全局变量——或者更好的是,弄清楚如何将它传递给函数。将它用作全局变量看起来像这样(同样,我展示了最简单的可能情况,不一定是 Python 的最佳用法):

class Info(object):  # or whatever you want to name the container
    """Holder for global information."""

info = Info()        # single instance we will use

def my_function():
    print "Here is some info:"
    print info.a, info.b, info.c

info.a = 3
info.b = 8
info.c = []

if __name__ == '__main__':
    my_function()
Run Code Online (Sandbox Code Playgroud)

同样,我可能会info改为传递给函数。但是由于您的问题是关于全局的,因此这里显示为全局。