関数内のすべての変数をグローバルにする簡単な方法はありますか?
関数に20個の奇妙な変数があり、それらを1つずつグローバルに命名しても、いいコードにはなりません...とにかく私には:)
関数内のすべての変数をグローバルにする簡単な方法はありますか?
関数に20個の奇妙な変数があり、それらを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}
これを行う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()
これは良いスタイルの例です (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()
それらすべてをグローバルとして宣言する方法はありません。あなたは本当にそうしたくありません。これらの20個の変数は、おそらく代わりに20個の属性を持つオブジェクトに変換する必要があります。
The simplest solution is to have only a single global — or, better yet, to figure out how to pass it in to the function. Using it as a global would look like this (again, I am showing the simplest possible case, not necessarily the best use of 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()
Again, I would probably pass info
to the function instead. But since your question was about a global, it's shown here as a global.