简体   繁体   English

如何在新的 class 中实例化 object?

[英]How to instantiate an object in a new class?

A bit of an odd question, but I'm wondering how to import an object from one class to another.有点奇怪的问题,但我想知道如何将 object 从一个 class 导入另一个。 I imagine adding more class methods and attributes as I expand my program, and I still want to be able to use old data.我想在扩展程序时添加更多 class 方法和属性,并且我仍然希望能够使用旧数据。 I am thinking something as follows:我的想法如下:

class old_obj:

    def __init__(self, text):
        self.name = text

    def set_amount(self, num):
        self.amount = num

    def introduce_yourself(self):
        print("I am {} and I am {} many".format(self.name, self.amount))

oldest = old_obj("myself")
oldest.set_amount(15)
also_old = old_obj("Bach")

class new_obj:
    def __init__(self):
        #some code
    #more code

I want to be able to write something like:我希望能够写出类似的东西:

renewed = new_obj(oldest)
also_new = new_obj(also_old)

Here, I want to retain the 15 from oldest.amount , but not complain that also_old.amount is None .在这里,我想保留oldest.amount中的15 ,但不要抱怨also_old.amountNone In particular, I want to retain any attributes that oldest has, while not requiring that it have all possible attributes.特别是,我想保留oldest的所有属性,而不要求它具有所有可能的属性。 Is there a way for me to copy over instances of a class to a new class?有没有办法让我将 class 的实例复制到新的 class?

Edit : edited for clarity编辑:为清楚起见进行了编辑

You could copy the object instance dict to the new class.您可以将 object 实例字典复制到新的 class。

from copy import deepcopy

class old_obj:

    def __init__(self, text):
        self.name = text

    def set_amount(self, num):
        self.amount = num

    def introduce_yourself(self):
        print("I am {} and I am {} many".format(self.name, self.amount))

oldest = old_obj("myself")

class new_obj:
    def __init__(self, my_old_obj):
        for var, val in my_old_obj.__dict__.items():
            setattr(self, var, deepcopy(val))
        #some code
    #more code

newest = new_obj(oldest)

I did a deepcopy of the value assuming you want unique values in the new object.假设您想要新的 object 中的唯一值,我对值进行了深度复制。 But that can also be problematic because not everything can be copied (file objects for instance).但这也可能有问题,因为并非所有内容都可以复制(例如文件对象)。 There can be other oddities when duplicating attributes such as what you want to do with a generator.复制属性时可能会出现其他奇怪的情况,例如您想用生成器做什么。 And if this is something like a GUI widget, it could get stranger still.如果这是一个类似于 GUI 小部件的东西,它可能会变得更加陌生。

But for a lot of object types, this would work.但是对于很多 object 类型,这会起作用。

You can simply initialize the new object by passing it the old one.您可以简单地通过传递旧的 object 来初始化新的 object。

class old_obj:
    def __init__(self, text):
        self.text = text

oldest = old_obj("myself")

class new_obj:
    def __init__(self, old_inst):
        self.text = old_inst.text 

renewed = new_obj(oldest)

print(renewed.text)

First, make your new_obj class inherit from old_obj , so that new_obj has all the methods old_obj had:首先,让你的new_obj class 继承自old_obj ,这样new_obj就拥有old_obj的所有方法:

class new_obj(olb_obj):

Then, in __init__ method of the new class you can check what is passed as the argument - a string or an object:然后,在新 class 的__init__方法中,您可以检查作为参数传递的内容 - 字符串或 object:

    def __init__(self, arg):
        if isinstance(arg, str):
            self.text = arg
        elif isinstance(arg, old_obj):
            self.text = arg.text 
        else:
            raise TypeError

Slightly different take:略有不同的取法:

Your new class has a set of concerns that are probably similar to your old class.您的新 class 有一组可能与您的旧 class 类似的问题。 This should guide the way you update it and build out the behavior in question.这应该指导您更新它并建立有问题的行为的方式。 With this in mind...考虑到这一点...

  1. Provide a class method in your new class to allow construction of the new object from the old object.在新的 class 中提供 class 方法,以允许从旧的 ZA8CFDE6331BD59EB2AC96F8911ZB4 构造新的 object。 Don't make this behavior a part of __init__ .不要让这种行为成为__init__的一部分。 Your __init__ should have a more limited responsibility.您的__init__应该承担更有限的责任。 For the class method, updating the new object's __dict__ using the old object's __dict__ would do the job.对于 class 方法,使用旧对象的__dict__ __dict__可以了。

  2. Don't use inheritance to make new versions of classes.不要使用 inheritance 来制作新版本的类。 Use inheritance to move from general to specific or abstract to concrete.使用 inheritance 从一般到具体或从抽象到具体。 Otherwise, you end up with code that is hard to understand and update.否则,您最终会得到难以理解和更新的代码。 (Imagine several generations down of just sub-classing in order to add some new methods.) (想象一下为了添加一些新方法而只进行子类化的几代人。)

  3. If the number of methods and attributes is growing, you might want to consider whether or not you're encapsulating data/behaviors that should be split into multiple classes.如果方法和属性的数量在增长,您可能需要考虑是否要封装应拆分为多个类的数据/行为。 The guiding principle is that you should encapsulate the data/behaviors that are likely to change together.指导原则是你应该封装可能一起改变的数据/行为。 That is, when you change the way you're implementing your program, things that don't need to change should probably be encapsulated separate from things that need changing.也就是说,当您更改实现程序的方式时,不需要更改的内容可能应该与需要更改的内容分开封装。 If you find that a lot of your static data is bound up with an object class that you're frequently updating (but wanting to just import the old data unchanged), then you've probably got two different sets of concerns, at least.如果您发现您经常更新的很多 static 数据与 object class 绑定在一起(但可能只想导入旧数据不变,那么至少有两组不同的问题)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM