Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的全局变量_Python_Global - Fatal编程技术网

python中的全局变量

python中的全局变量,python,global,Python,Global,我目前有一些类foo,其中包含一些变量,这些变量不仅在foo类的所有实例之间共享,而且还被其他类共享 i、 e 一种解决方案是生成a和b类变量,但在构造过程中如何干净地实现这一点?我可以把这两个类放在同一个文件中,让它们引用一些全局变量a和b吗?这种做法不好吗?您可以这样做: class Foo(object): def __init__(self, a, b): self.a = a self.b = b class Bar(Foo): pas

我目前有一些类foo,其中包含一些变量,这些变量不仅在foo类的所有实例之间共享,而且还被其他类共享

i、 e

一种解决方案是生成a和b类变量,但在构造过程中如何干净地实现这一点?我可以把这两个类放在同一个文件中,让它们引用一些全局变量a和b吗?这种做法不好吗?

您可以这样做:

class Foo(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b

class Bar(Foo):
    pass
通过从Foo继承,您也将采用Foo的构造方法,因此它将以相同的方式工作。如果需要覆盖它,可以在工具栏中以这种方式进行设置:

def __init__(self, a, b, c):
    super(Bar, self).__init__(a, b)
    self.c = c

super将首先调用您的基类的方法(在本例中为Foo),然后允许您根据需要添加,如果你感兴趣的话。

我不知道你说的施工过程中的清洁是什么意思

可以通过在函数外部定义类变量来使用类变量,如:

class A:
  x = 1
  def __init__(self):
     pass

只要在需要变量的时候调用A.x,在其他类中或任何地方

,因为您没有提供您的意图或实际情况,我只提供一些共享变量访问的方法

第一种选择:全球

a=b=None

class foo():
    def __init__(self, _a, _b):
        global a, b
        a, b = _a, _b

class bar():
    def __init__(self, _a, _b):
        global a, b
        a, b = _a, _b
第二种选择:foo's class vars

class foo():
    a = b = None
    def __init__(self, a, b):
        foo.a, foo.b = a, b

class bar():
    def __init__(self, a, b):
        foo.a, foo.b = a, b
第三种选择:继承

class foo():
    def __init__(self, a, b):
        self.a, self.b = a, b

class bar(foo):
    pass
第四种选择:外层舱

class outer():
    a = b = None
    class foo():
        def __init__(self, a, b):
            outer.a, outer.b = a, b

    class bar():
        def __init__(self, a, b):
            outer.a, outer.b = a, b
第五种选择:合规

class foo():
    def __init__(self, a, b):
        self.a, self.b = a, b

class bar():
    def __init__(self, a, b):
        self.foo = foo(a,b)
第六选项:外部函数局部变量的闭包

def outer():
    a = b = None
    class foo():
        def __init__(self, _a, _b):
            nonlocal a, b
            a, b = _a, _b

    class bar():
        def __init__(self, _a, _b):
            nonlocal a, b
            a, b = _a, _b

    ... #things with foo and bar
第七个选项:foo的_uinit _;局部变量上的闭包

class foo():
    def __init__(self, a, b):
        self.a, self.b = a, b
        class bar():
            nonlocal a, b
            #do things with a and b directly

        self.bar = bar()

通常的解决方案是创建一个存储共享信息的对象,然后在实例化需要它的类时传递它。这通常是某种配置信息,因此我们将调用Config类:

因为Python是鸭型的,所以任何对象都可以用来保存这个配置;它可以是类的实例,也可以是类本身。前者在运行时指定数据时非常方便。后者很方便,因为它允许程序员在编码时使用继承定义各种属性包。这里的Config类让您可以采用任何一种方式:您可以实例化它,用共享值传递关键字参数,或者您可以将其子类化,将共享值作为类属性提供

在Foo和Bar类中,您只需接受构造函数中的共享数据:

# these classes both need certain pieces of data
# but are not related by inheritance

class Foo(object):
    def __init__(self, shared):
        self.shared = shared

class Bar(object):
    def __init__(self, config):
        self.config = config
然后您可以实例化Config类,或者定义一个子类,并将结果对象传递给新对象:

# use an instance
adams_config = Config(text="Don't Panic", number=42)
foo1, bar1 = Foo(adams_config), Bar(adams_config)

# use a subclass
class LincolnConfig(Config):
    number = 87 
    text   = "Four score and seven years ago"
foo2, bar2 = Foo(LincolnConfig), Bar(LincolnConfig)
现在,Foo和Bar类的方法可以获取self.shared.number或self.config.text等来访问数据

由于各种类的实例都包含对同一对象的引用,因此任何类的任何实例都可以看到对这些对象之一的引用对例如adams_config或LincolnConfig的更改。如果这不是您想要的行为,您可以在实例化时从config对象中提取要冻结的数据,并将其设置为实例的属性

您也可以在不同的地方使用字典来访问数据,但我认为继承和属性访问语法的好处是使用类进行访问的一个很好的理由

您甚至可以使用一个全局配置对象作为默认值,这样,如果希望一切正常工作,就不需要显式指定它。在这里,我们只使用Config类本身,因为它已经为我们感兴趣的属性提供了默认值:

class Baz(object):
    def __init__(self, config=Config):
        self.config = config

通过使用这种方法而不是全局变量,您可以使使用对象的客户端更容易地拥有多个具有不同设置的实例,而不是将所有实例限制为一组设置。

您的问题并不清楚。这些变量是什么?他们是如何分享的?bar.\uuuInit\uuuuuo初始化foo的变量是没有意义的。foo的实例变量根本不共享。显示的代码中没有类变量。或者你想分享这些变量所包含的对象。如果你只是问我……能让它们引用一些全局变量吗?答案显然是肯定的。但你可能会问这能实现我想要的吗?或者这是实现我想要的最好方式吗?我们不知道你想要什么,所以没有办法回答。这不是一个问题,也不是一个问题。只有在符合情况的情况下,继承才是一个好的解决方案。继承不是为了重用,而是为了子类型。@Elazar:对不起,我不同意,因为它本身就是一种重用。@martineau:当然,子类型是类型的重用,通常也意味着接口等,但我想Elazar是想说继承是为了重用类型、接口等,而不是重用实现、存储、,等等,这是一个正确的观点。有一些东西落在中间,正在讨论,比如布局,但这些东西在Python中很少有。”阿巴纳特:我仍然不同意。继承是为了重用超类的属性或方面,不管是什么
没有人是非法的或禁止进入的。当然,这并不意味着它们在所有方面都是平等的,因为有些类可能比其他类更脆弱,导致两个类之间的耦合比明智的要多。@martineau:让我们这样试试:根据经验,代码重用的继承是不好的,除非在某些特殊情况下,例如ABC混合。然而,与任何经验法则一样,它不是僵硬不变的,而且与大多数经验法则一样,Python的动态性和灵活性意味着异常比Java中的异常更容易被激发。另外,你的第五个选择是错误的;你想要像self.foo=fooa,b这样的东西。还有你的第六个。我不确定您在那里尝试了什么,但该代码只是将a和b重新绑定到传递给每个类初始化的实际参数。此外,第7个功能与第6个功能相同;只是你正在使用隐式非局部,或者,如果你分配给a或b,则不是…,并捕获闭包以供以后使用。@abarnert是的,我会将def和5归咎于深夜:我不理解你对7的评论。它不是一个隐式的非局部的-那里应该只有阅读,没有作业;如果不赋值,则它隐式地是非本地的。如果在定义时有一个本地名称,则它将成为一个闭包加载;如果不完全像添加了一个非本地语句,则它将成为一个全局加载。6和7之间的区别是6允许赋值,7不允许,但将它们称为函数局部和闭包会产生误导,如果你不赋值,它们都是函数局部变量的闭包,如果你赋值,7根本不使用闭包。@abarnert我想我理解你的意思。我改变了描述,以减少误导。我要说的是,在6中,你以一种对称的方式对待a和b,即保留全局变量,7只适合非常特殊的情况。
# use an instance
adams_config = Config(text="Don't Panic", number=42)
foo1, bar1 = Foo(adams_config), Bar(adams_config)

# use a subclass
class LincolnConfig(Config):
    number = 87 
    text   = "Four score and seven years ago"
foo2, bar2 = Foo(LincolnConfig), Bar(LincolnConfig)
class Baz(object):
    def __init__(self, config=Config):
        self.config = config