2012-09-29 23 views
0

我使用@classobj實現了幾個構造函數。我不僅設置變量,但還呼籲在新的類方法:類方法構造函數的類型錯誤

class Example: 
    def __init__(self): 
     pass 

    @classmethod 
    def constructor1(cls,x,y): 
     self=cls 
     self.__x = x 
     self.__somemethod(self,y) 

    ... 

我得到以下錯誤:

unbound method __somemethod() must be called with Example instance as 
first argument (got classobj instance instead) 

我該如何解決這個問題呢?

+2

使用'cls'而不是'self'然後做'self = cls'的原因是什麼? –

+0

你的用例是什麼 - 你是否試圖使用'@ classmethod'作爲工廠函數? –

回答

2

如果你想你的類方法是一個構造函數,你可能要被創造時,我們獲得通過作爲cls類的一個實例。我懷疑你正在嘗試使用self = cls這一行來執行此操作,但實際上並未創建新實例,因爲您忽略了放置括號。還有一些其他問題,但我認爲這是關鍵問題。這裏有一個固定的構造函數:

@classmethod 
def constructor1(cls,x,y): 
    self=cls()    # parentheses added, to make it a call 
    self.__x = x 
    self.__somemethod(y)  # self is not needed as a parameter here 
    return self    # return the new instance 
+0

這就是我剛發現的(完全不知道)(請參閱下面的自己的答案),謝謝! –

+0

在我的例子中,我也忘了'return self'。優秀的答案。 +1 –

2

看起來像__somemethod不是類方法,而是一種「正常」方法。 正常的方法期望一個實際的實例作爲第一個參數,而不是一個類。 而且由於constructor1裝飾爲@classmethod,因此cls是本身類別 - 您將其傳遞給__somemethod。 這是行不通的。

您應該重新考慮您的設計方法。

附錄:

也許你的意思是這樣的?

@classmethod 
def constructor1(cls, x, y): 
    newinst = cls() 
    newinst.__x = x 
    cls.__somemethod(newinst, y) 

那會更好的寫法如下其次,雖然:

@classmethod 
def constructor1(cls, x, y): 
    newinst = cls() 
    newinst.__x = x 
    newinst.__somemethod(y) 

其實,我喜歡neighter方法 - 好像超集成的給我代碼異味。

1

這可能是什麼,我認爲你想達到一個模板...

import random 

class Something(object): 
    def __init__(self, value, **kwargs): 
     self.value = value 
     for k, v in kwargs.iteritems(): 
      setattr(self, k, v) 
    @classmethod 
    def from_iterable(cls, iterable): 
     return cls(sum(iterable), description='came from from_iterable') 
    @classmethod 
    def make_random(cls): 
     return cls(random.randint(1,1000), is_random=True) 

a = Something.from_iterable([1, 2, 3]) 
b = Something.make_random() 
c = Something(56) 

for obj in (a, b, c): 
    print type(obj), obj.value 

<class '__main__.Something'> 6 
<class '__main__.Something'> 308 
<class '__main__.Something'> 56 
0

由於ch3ka的回答和Tim Pietzcker的評論,我發現我的錯誤:我從http://jjinux.blogspot.co.at/2008/11/python-class-methods-make-good.html使用的工廠方法並且忘記了self=cls()中的()。現在,它工作得很好:

class Example: 
    def __init__(self): 
     pass 

    @classmethod 
    def constructor1(cls,x,y): 
     self=cls() 
     self.__x = x 
     self.__somemethod(self,y) 

    ... 
相關問題