如何在python中实例化类之后直接返回对象?

2024-05-12 23:52:04 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我有这些课程:

class MyObject:
    def __init__(self, version):
        self.version = version

class Builder:
    def __init__(self,version='0.0.1'):
        self.version = version

    def build(self):
        return MyObject(self.version)

是否可以通过简单地调用

versioned_obj = Builder('0.0.1') 
#instead of going through
builder = Builder('0.0.1')
versioned_object = builder.build()

什么

已尝试使用__init__(),但必须返回None


Tags: ofbuildselfobjreturninitversiondef
2条回答

你有一个类MyObject。如果要在单个调用中实例化MyObject,则根本不需要构建器,只需直接初始化MyObject

versioned_obj = MyObject('0.0.1')

回到您所问的,关于使用Builder类而不调用build():虽然可以让生成器类的构造函数通过重写__new__返回MyObject,但我确实不建议这样做

如果不理解为什么有一个构建器类(似乎什么也不做),就很难推荐替代方案,但肯定有一些。根据您展示的代码,我不能推荐任何一种,因为它们毫无理由地增加了复杂性。但也许他们会给你一个适合你没有展示的代码的想法

生成器作为函数

在上面的示例中,没有明显的理由说明构建器需要存在,更不用说是一个类,但是如果您想要一个构建器,而它不必是一个类,那么它可以只是一个函数:

def build_myobj(version):
    return MyObject(version)

versioned_obj = build_myobj('0.0.1')

生成器工厂方法

或者,如果Builder类确实适合作为一个类,但您还没有向我们说明原因,则可以向Builder添加工厂方法:

class Builder:
    def __init__(self,version='0.0.1'):
        self.version = version

    def build(self):
        return MyObject(self.version)

    @staticmethod
    def factory(version):
        return Builder(version).build()

versioned_obj = Builder.factory('0.0.1')

使用生成器的函数

如果不想修改生成器类,但只需要一个调用:

def build_myobj(version):
    return Builder(version).build()

versioned_obj = build_myobj('0.0.1')

您所指的似乎是object.__new__方法。创建类的实例时,将调用__new__方法来创建并实际返回将被分配的对象,然后在分配之前调用它的__init__方法

示例

class otherclass:
    def __init__(self, *args, **kwargs):
        print('hello from otherclass')

class myclass:
    # __new__ is a staticmethod by default so it recieves cls rather than self (no self exists yet..)
    def __new__(cls, *args, **kwargs):
        print('creating new instance of otherclass from myclass')
        return otherclass(*args, **kwargs)

调用myclass()打印:

creating new instance of otherclass from myclass 
hello from otherclass
Out[2]: <__main__.otherclass at 0x22192e0a898>

注意:我没有把它包括在示例中,但是__init__被调用的*args, **kwargs__new__相同

相关问题 更多 >