是否可以将类类型的对象作为参数传递给另一个类,这样我就不必再次初始化? (Python 3.x)

Posted

技术标签:

【中文标题】是否可以将类类型的对象作为参数传递给另一个类,这样我就不必再次初始化? (Python 3.x)【英文标题】:Is it possible to pass an object of type class as an argument in another class so that I don't have to initialize again ? (Python 3.x) 【发布时间】:2021-10-02 11:02:59 【问题描述】:

我使用两个类FooBar,后者继承自第一个。 运行 Foo 可能需要一些时间,当我需要运行 Bar 时,我不想再次运行它。

class Foo:
    def __init__(self):
        self.something = "something"
        self.another_variable = 10
        # and many other variables

    def do_something(self):
        self.something = "something else"
        self.another_variable = 100
        # and more operations on the other variables

        print(f"This takes some time. We have self.something!r now.")

foo = Foo()
foo.do_something() # This takes some time. We have 'something else' now.


class Bar(Foo):
    def __init__(self, foo=None):
        if isinstance(foo, Foo):
            self.something = foo.something
            self.another_variable = foo.another_variable
            # ...
            # this is the part that I want to generalize
            # with something that would intuitively look like 'self = foo'
        else:
            Foo.__init__(self)
            self.do_something()

    def print_something(self):
        print(self.something)

bar = Bar(foo=foo)
bar.print_something() # AttributeError: 'Bar' object has no attribute 'something'

我想做类似self = foo 这样的事情,这样使用foo 完成的所有事情都可以传递给bar,而无需再次运行代码。

我知道我可以先执行Bar().foo(),然后再执行Bar().bar(),这就是我现在实际执行的操作,但我只想在稍后阶段初始化bar

有可能吗?

【问题讨论】:

由于 Bar 是 Foo 的子类,当且仅当 Bar 实例化不包含 Foo 时,创建一个初始化 foo 的 Bar 实例。仅仅因为你定义了一个类,它在实例化之前不会执行,所以 Foo 只实例化一次。 如果您在整个项目中只需要一次Foo,您可能需要研究另一种设计。类似于某种单例或将其添加为静态值。所以问题是,你只需要一次 Foo 吗? 我想在使用Bar之前多次使用Foo。然后,当foo 的参数足够好时,我想将它的每个元素和方法传递给bar,而无需再次运行(也无需手动执行)。我目前所做的是多次初始化Bar,但只运行Foo 中的方法,直到我有正确的参数,然后我才使用Bar 的其余部分。有用。但它不是那么漂亮。 在我看来 Foo 有一个或一组方法应该被编码为一个独立的函数而不是 Foo 的一部分。在这种情况下,可以在需要时调用函数,并且仅在需要时调用。该函数可以作为输入 Foo 和 Bar 【参考方案1】:

如果我没听错的话,你可以用一个标志(这里命名为self.processed)来做到这一点:

from time import sleep


class Foo:
    def __init__(self):
        self.something = "something"
        self.processed = False

    def do_something(self):
        self.something = "something else"
        sleep(1)
        self.processed = True
        print(f"This takes some time. We have self.something!r now.")


foo = Foo()
foo.do_something()  # This takes some time. We have 'something else' now.


class Bar(Foo):
    def __init__(self, foo=None):
        if isinstance(foo, Foo):
            super().__init__()

            if not foo.processed:
                self.do_something()

    def print_something(self):
        print(self.something)


bar = Bar(foo=foo)
bar.print_something()

输出:

This takes some time. We have 'something else' now.
something else

所以在Bar 的初始化中,do_something 方法只有在我们之前没有调用过的情况下才会被调用(在foo 上)

【讨论】:

谢谢@SorousH 的回答,但这不是我要找的:我正在寻找一个(或左右)一行,它可以传递一个类中的每个变量和方法(例如@ 987654327@)到另一个(例如Bar)。我还没找到方法【参考方案2】:

所以我通过遍历属性找到了解决方案:

for attr in foo.__dict__.keys():
    exec(f"self.attr = foo.attr")

这是完整的工作示例:

class Foo:
    def __init__(self):
        self.something = "Something"
        self.another_variable = 10
        # and many other variables

    def run_foo(self):
        self.something = "Something else"
        self.another_variable = 100
        # and more operations on the other variables
        print(f"This takes some time. We have self.something!r now.")

foo = Foo()
foo.run_foo()               # This takes some time. We have 'something else' now.
class Bar(Foo):
    def __init__(self, foo=None):
        if isinstance(foo, Foo):
            for attr in foo.__dict__.keys():      # this is the solution
                exec(f"self.attr = foo.attr") #
            print("'run_foo' is not called, so there is no waste of time.")
        else:
            Foo.__init__(self)
            self.run_foo()

    def print_something(self):
        print(self.something)

bar = Bar()                 # This takes some time. We have 'something else' now.
bar.print_something()       # Something else

bar = Bar(foo=foo)          # 'run_foo' is not called, so there is no waste of time.
bar.print_something()       # Something else


【讨论】:

以上是关于是否可以将类类型的对象作为参数传递给另一个类,这样我就不必再次初始化? (Python 3.x)的主要内容,如果未能解决你的问题,请参考以下文章

试图将类作为参数传递给不同的类构造函数,但出现“转换”错误

将类对象实例作为参数从 main() 传递给另一个类对象实例

对象作为参数传递给另一个类,通过值还是引用?

如何将类方法作为参数传递给该类外部的函数?

Actionscript 3:将类作为参数传递

将类作为参数传递给方法,然后调用静态方法