2017-08-08 131 views
2

我有一個類,其中包含一些成員x初始化類成員(比方說,有些數據是由所有實例需要的,但獨立於它們的):如何使用類方法

class Foo(object): 
    x = 23 

    # some more code goes here  

現在,確定x的過程變得更加複雜再加上我希望能夠在特定的時間,以「刷新」 x,所以我決定寫一個額外的功能,它

class Foo(object): 
    @classmethod 
    def generate_x(cls): 
     cls.x = 23 

    # some more code goes here 

然而,這個類的定義缺乏對初始化呼叫。

我試過到目前爲止:

這不起作用:

class Foo(object): 

    # generate_x()  # NameError: name 'generate_x' is not defined 
    # Foo.generate_x() # NameError: name 'Foo' is not defined 

    @classmethod 
    def generate_x(cls): 
     cls.x = 23 

這工作,但不太清楚,因爲代碼用於類定義之外

class Foo(object): 

    @classmethod 
    def generate_x(cls): 
     cls.x = 23 

    # ... 
Foo.generate_x() 

有沒有更好的替代品?在這裏使用@classmethod最好的方法?我正在搜索的是一個類相當於__init__

考慮代碼的清晰度,是否存在比後者更好的方式使用自動功能來實例化Foo.x?實現這一

+1

你試圖解決的實際問題是不是由'Foo.x = 42'解決? – NPE

+0

正如我所說的,'x'的構造更復雜,'Foo.x = 23'只是一個例子。我想(i)使用*函數*自動實例化'Foo.x',並且我希望它自動發生。 – flonk

+0

如果您正在尋找__init__'的'類相當於再看看這篇文章在Python元編程:https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/做一些試驗'__new__'和'__prepare__'。 – Szabolcs

回答

1

一種方式是通過使用裝飾:

def with_x(cls): 
    cls.generate_x() 
    return cls 

@with_x 
class Foo(object): 
    @classmethod 
    def generate_x(cls): 
     cls.x = 23 

(這就是說,我個人只是調用Foo.generate_x類聲明後明確,並且完全避免所有的魔法。)

+0

謝謝,我會堅持'Foo.generate_x()',已經問* *是否有一個更優雅的方式,「不」也是一個完美的答案。 – flonk

0

使用描述符。

class Complicated: 
    def __init__(self, location, get_value): 
     self.location =location 
     self.get_value = staticmethod(get_value) 
    def __get__(self, obj, owner): 
     try: 
      a = getattr(owner, self.location) 
     except AttributeError: 
      a = self.get_value() 
      setattr(owner, self.location, a) 
     return a 

class My class: 
    x = Complicated ('_x', get_x) 
相關問題