我正在使用@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)
如何解决此问题?
答案 0 :(得分:3)
如果您希望类方法成为构造函数,您可能希望创建一个以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
答案 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)
实际上,我喜欢更直接的方法 - 看起来像是对我来说过于复杂的代码。
答案 2 :(得分: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
答案 3 :(得分:1)
感谢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)
...