Подтвердить что ты не робот

Сделать все переменные в функции Python глобальными

Есть ли простой способ сделать все переменные в глобальной функции?

У меня есть 20 нечетных переменных в функции и их имена глобально по одному не делают хороший код... мне все равно:)

4b9b3361

Ответ 1

Предупреждение: не пытайтесь сделать это дома, вы можете сжечь его.

В ходе нормального ежедневного программирования нет законных оснований делать следующее. Просмотрите другие ответы на этот вопрос для более реалистичных альтернатив.

Я едва могу представить, почему вы хотели бы это сделать, но вот способ сделать это:

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}

Ответ 2

Невозможно объявить их глобальными, и вы действительно этого не хотите. Эти 20 переменных, вероятно, должны быть превращены в объект с 20 атрибутами.

Ответ 3

Питонический способ сделать это - либо сохранить переменные в локальной области (т.е. определить их внутри каждой функции), и передать их между функциями в качестве аргументов/возвращаемых значений; или сохранить ваши переменные в качестве атрибутов объекта или класса, создавая ваши методы "функции" в этом классе. В любом случае это нормально, но ключевое слово 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()

Вот пример хорошего стиля (с ООП):

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()

Ответ 4

Самое простое решение - иметь только один глобальный - или, еще лучше, выяснить, как передать его функции. Использование этого как глобального будет выглядеть так (опять же, я показываю простейший возможный случай, не обязательно наилучшее использование 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()

Опять же, я бы, скорее всего, передал info функции. Но так как ваш вопрос был о глобальном, он показан здесь как глобальный.