2017-07-19 100 views
0

我想分享跨类的不同实例的数据参数,但数据必须由外部提供的第一次创建的类。如何初始化类变量只使用一次传递给init

我已经写了下面的代码片段。

class Foo(object): 

    _config = False 
    eggs = None 

    def __init__(self, spam, eggs=None): 

     if Foo._config: 
      # Assume initialized and eggs exists 
      print(Foo.eggs) 

     else: 
      if eggs is None: 
       raise ValueError('eggs must be provided the first time') 
      else: 
       Foo.eggs = eggs 
       Foo._config = True 
       print("Scrambled {}?".format(Foo.eggs)) 

     self.spam = spam 
     print("Class variable - eggs: {}".format(Foo.eggs)) 
     print("Instance variable - spam: {}".format(self.spam)) 

这似乎工作...

>>>Foo._config 
False 
>>>a = Foo('chicken', 'eggs')  
Scrambled eggs? 
Class variable - eggs: eggs 
Instance variable - spam: chicken 
>>>Foo._config 
True 

和第二时间不会引发错误和股票类变量

>>>b = Foo('duck') 
eggs 
Class variable - eggs: eggs 
Instance variable - spam: duck 

我的问题是,这是否是一个方法?我已经看到这个问题,这表明包含__init__这些只被调用一次的东西是一个坏主意,我应该使用一个元类?

我的理由是,鸡蛋实际上将包含一个非常大的熊猫数据框,我不想重复每个实例。

+1

你为什么不只是完全相同的大型熊猫数据帧初始化?参考的成本可以忽略不计。 –

+0

您是否希望班级的所有实例共享相同的熊猫数据框,例如:从一个实例修改它会修改所有? – Erich

+0

@ juanpa.arrivillaga请原谅我的无知,但如果数据帧是'df'然后调用'self.df = df'内'__init__'每次都会引用同一个数据帧? – drstevok

回答

0

一种方式做到这一点是建立一个@classmethod,你会以实例的所有对象共享你的常数值在一开始打电话。

+0

我该如何确保这个运行只有一次?是否有一个相当于'__init__'的类 – drstevok

+0

不是我所知道的。在我们的代码库中,我们有一个需要这种行为的类,所以我们创建了一个'initialize'类方法。当你检查你的'if egg is None'时,我们检查classmethod至少被调用过一次。 – Y0da

+0

好的。这听起来像比我更整洁的方法。谢谢 – drstevok

1

我建议不要使用类的命名空间。 参见:

class holder(): 
    x = 5 
    def __init__(self): 
     self.x = 6 
     return; 

alpha = holder() 
beta=holder() 
beta.x = 4 
holder.x = 100 
print(holder.x) 
print(alpha.x) 
print(beta.x) 

> 100 
> 6 
> 4 

该变量的范围被快速稀释。我会保留常量的类名称空间。

如果尝试设置在类命名空间的引用,那么你将收到生成熊猫数据帧。在创建对象之前,在代码的某个地方创建它可能会更容易,然后通过引用每个类来传递它。

如前所述通过@ juanpa.arrivillaga:self.df = DF