Python Classmethod:在函数中使用函数

Python Classmethod:在函数中使用函数,python,Python,我使用@classmethod为类创建构造函数。在这个构造函数中,调用一个函数,然后调用另一个函数。但要么这不起作用,要么(更有可能)我正在做一些事情使它不起作用。下面是一个缩影示例: class testclass: def __init__(self, x): self.x = x @classmethod def constructor(cls, x): adj_x = cls.outer_adjust(cls, x)

我使用
@classmethod
为类创建构造函数。在这个构造函数中,调用一个函数,然后调用另一个函数。但要么这不起作用,要么(更有可能)我正在做一些事情使它不起作用。下面是一个缩影示例:

class testclass:
    def __init__(self, x):
        self.x = x

    @classmethod
    def constructor(cls, x):
        adj_x = cls.outer_adjust(cls, x)
        return testclass(adj_x)

    def outer_adjust(self, x):
        return self.inner_adjust(x)

    def inner_adjust(self, x):
        return x + 1

test_instance = testclass.constructor(4)
这将生成一条错误消息:

inner_adjust() missing 1 required positional argument: 'x'
我可以通过显式地将self传递给
internal\u adjust
,例如

def outer_adjust(self, x):
    return self.inner_adjust(self, x)
但是这意味着
outer\u adjust
方法不能在
构造函数之外使用,这不是我想要的

感谢您的帮助

下面是一个更详细的示例,其中显示了两个构造函数。我试图遵循中描述的构造函数方法 这本质上是构造函数进行一些处理,以确定在实例化类时应该将哪些变量传递给init。 两个构造函数都给出相同的错误:

if_char_is_z_make_it_a() missing 1 required positional argument: 'char_input'
与前面一样,我需要能够使用if_char_is_make_it_构造函数之外的函数(即,在正常使用该类时)


基本上,你在这里所做的应该通过作为构造函数的

class testclass:
    def __init__(self, x):
        self.x = x

    def __new__(cls, *args, **kwargs):
        instance = super(testclass, cls).__new__(cls, *args, **kwargs)
        instance.outer_adjust(args[0])
        return instance

    def outer_adjust(self, x):
        return self.inner_adjust(x)

    def inner_adjust(self, x):
        self.x = x + 1

test_instance = testclass(4)

当您从
constructor
调用
cls.outer\u adjust
时,您正在调用unbound
outer\u adjust
方法

因此,将类本身作为
self
传递,而不是将实例传递给希望接收实例作为参数的方法

尽管如此,没有真正的理由使用
构造函数
方法。这正是
\uuuu init\uuuu
的目的

class testclass:
    def __init__(self, x):
        self.x = self.outer_adjust(x)

    def outer_adjust(self, x):
        return self.inner_adjust(x)

    def inner_adjust(self, x):
        return x + 1

test_instance = testclass(4)
如果您确实需要在实例化之前完成
x
上的转换,请使用。虽然,这通常是不必要的

多个构造函数 如果出于某种原因,您仍然需要一个
构造函数
方法,例如,如果您需要多个构造函数。请记住,
outer\u adjust
internal\u adjust
是实例方法,这意味着必须在创建实例后调用它们

class testclass:
    def __init__(self, x):
        self.x = x

    @classmethod
    def constructor1(cls, x):
        instance = cls(x)
        instance.outer_adjust()
        return instance

    @classmethod
    def constructor2(cls, x):
        instance = cls(x)
        instance.inner_adjust()
        return instance

    def outer_adjust(self):
        print('Do something else')
        return self.inner_adjust()

    def inner_adjust(self):
        self.x += 1

作为旁注,请注意我如何不需要调用
testclass
,而只是在构造函数方法中调用
cls
。因为这是一个类方法,所以我们不需要显式地命名该类。这更好,特别是如果你要使用继承。

你在滥用
自我。class方法的要点是使用
cls
参数作为构造函数,而不是通过
testclass(adj_x)
显式命名类。另外,在
cls.outer\u adjust(cls,x)
调用期间,您传递的是类而不是实例,这恰好起作用,因为您没有使用任何实例属性

至于你的问题,没有办法避免
x
参数
internal\u adjust
将某些值增加
1
,因此您必须给它一些可以增加的值。我们的想法是

def constructor(cls, x):
    return cls(x)

def inner_adjust(self):
    return self.x += 1
然后做一些类似的事情

object= testclass.constructor(12)
object.inner_adjust()

谢谢-我确实理解你的意思,但这是一个具有多个构造函数的类(从我缩短的示例中可能不明显),所以我不能只使用init。@ChrisHarris您可能需要分享更多详细信息。你所描述的看起来有点像代码气味,你可能想考虑一个更好的方法来做,例如使用继承。感谢详细的响应。我试图使用这里描述的构造函数的使用方法:在这里,构造函数函数完成了大部分工作,以确定在通过init实例化类时最终应该传递哪些变量。我将编辑我的原始文章,包括一个更详细的例子,希望能让它更清楚一点。我发现代码在我的设置中不起作用。在使用构造函数计算@classmethod函数中的变量,然后使用它们基于init创建一个实例时,我还想坚持通常的方法。此外,我应该指出,在您的示例中,
internal\u adjust
只返回值,而
adj\u x
被丢弃,所以
\uuuu new\uuuuu
在这里什么都不做。@OlivierMelançon是的,你是对的,但可能是一些占位符…@OlivierMelançon是的,谢谢,老实说,从一开始你就没有领会你的想法,不需要设置
调整x
变量谢谢你的回复。我明白你所说的使用cls而不是命名类来创建实例。然而,我认为您描述的方法在这种情况下不起作用,因为我需要在代码的其他地方使用internal_adjust函数,在这里我可能希望传递self.x以外的参数。@ChrisHarris:1)这就是classmethod的要点。如果使用类的名称,则继承失败,或者名称更改。2) 如果您使用的不是
self
属性,而是参数,那么它可能应该是
@staticmethod
object= testclass.constructor(12)
object.inner_adjust()