使用classmethod构造函数键入错误

时间:2012-09-29 10:24:54

标签: python constructor class-method

我正在使用@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)

如何解决此问题?

4 个答案:

答案 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被装饰为@classmethodcls是类本身 - 您将其传递给__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)

    ...