简体   繁体   English

如何在python中将实例从一个类切换到另一个类?

[英]How can I switch a instance from one class to another in python?

I'm new to programming and just learned about the concept of object oriented programming.我是编程新手,刚刚了解了面向对象编程的概念。

I'm trying to find a way to modify a existing instance make it belong to another class, by this I mean inheritance most of its property but not methods.我试图找到一种方法来修改现有实例使其属于另一个类,我的意思是继承它的大部分属性而不是方法。

Like for us human to get a new job (have different method than the old one) but still is the same person (retain some property like age, name and so on).就像我们人类得到一份新工作(方法与旧工作不同)但仍然是同一个人(保留一些财产,如年龄、姓名等)。

I'm not good at describing my question, so I'll paste my example code down here.我不擅长描述我的问题,所以我会在这里粘贴我的示例代码。

from random import randrange

class human(object):
    def __init__(self,name,age) -> None:
        self.name= name
        self.age = age
        self.job = False

    def introduce(self):
        print(f"My name is {self.name}, I'm {self.age} years old now.")

    def getjob(self,tfunc):
        return tfunc(self.name,self.age)

class teacher(human):
    def __init__(self,name,age) -> None:
        self.name= name
        self.age = age
        self.job = 'teacher'
        self.studentamount = randrange(12,24)
    
    def introduce(self):
        print(f"My name is {self.name}, I'm a {self.job} and have {self.studentamount} students. I'm {self.age} years old now.")
    # imagine more method has same name as those in worker class down here.

class worker(human):
    def __init__(self,name,age) -> None:
        self.name= name
        self.age = age
        self.job = 'worker'
        self.workhour = randrange(8,12)

    def introduce(self):
        print(f"My name is {self.name}, I'm a {self.job} and I work {self.workhour} hour per day. I'm {self.age} years old now.")
    # imagine more method has same name as those in teacher class down here.

a = human('foo',31)
a.introduce()

a.age += 1
a = a.getjob(worker)
a.introduce()

a.age += 8
a = a.getjob(teacher)
a.introduce()

Output will be:输出将是:

> My name is foo, I'm 31 years old now.
> My name is foo, I'm a worker and I work 9 hour per day. I'm 32 years old now.
> My name is foo, I'm a teacher and have 15 students. I'm 40 years old now.

Some backgrounds:一些背景:

I was writing a "AI" for a minigame as coding practice, I want the "AI" have very different behavior sometimes.我正在为小游戏编写“AI”作为编码练习,我希望“AI”有时具有非常不同的行为。

Such as when take certain amount of damage become defensive which have different sets of movement and never think about attack at all, only 10 or so turns after will it fallback to the default behavior.比如当受到一定程度的伤害时变成防御性的,有不同的动作,根本不考虑攻击,只有10个左右的回合才会回退到默认行为。

And I want to call instance.act() inside the game loop for every "AI", instead of instance.act_default() and instance.act_defensive().我想在游戏循环中为每个“AI”调用 instance.act(),而不是 instance.act_default() 和 instance.act_defensive()。

So I think that so call "polymorphism" from what I just learn fit this perfectly, then I encountered this problem.所以我认为我刚刚学到的所谓的“多态性”非常适合这个,然后我遇到了这个问题。

What I'm seeking is something like getjob() in my example code, but with less jank.我正在寻找类似于我的示例代码中的 getjob() 的东西,但卡顿更少。

I would imagine when the class get more property, the getjob() method will become really clustered and unreadable and that's not what I want.我想当类获得更多属性时, getjob() 方法将变得非常聚集且不可读,这不是我想要的。

And maybe not creating a new human instance replacing the old one every time when that human gets a new job.并且可能不会在人类每次获得新工作时创建一个新的人类实例来替换旧的人类实例。

And maybe instead of a = a.getjob(teacher) use something like a.getjob(teacher) and self = tfunc(self.name,self.age) inside getjob() method (which I try and will not work).也许而不是a = a.getjob(teacher)在 getjob() 方法中使用类似a.getjob(teacher)self = tfunc(self.name,self.age)东西(我尝试过但不起作用)。


I edit this because my original question is too vague and not specific.我编辑这个是因为我原来的问题太模糊而且不具体。

I change as little as I can, to describe what I'm trying to achieve more clearly.我尽可能少改变,以更清楚地描述我想要实现的目标。 And I provide some background as I hope it would be helpful.我提供了一些背景,因为我希望它会有所帮助。

When you have a subclass you can use super() to use the superclass init to avoid code duplication.当您有一个子类时,您可以使用super()来使用超类 init 以避免代码重复。 Also, now the if statement in introduce has to check if job attribute exists:此外,现在introduce的 if 语句必须检查job属性是否存在:

class human(object):
    def __init__(self,name,age) -> None:
        self.name= name
        self.age = age

    def introduce(self):
        if hasattr(self, "job"):
            print(f"My name is {self.name}, I'm a {self.job}, I'm {self.age} years old now.")
        else:
            print(f"My name is {self.name}, I'm {self.age} years old now.")

class teacher(human):
    def __init__(self,name,age) -> None:
        super().__init__(name, age)
        self.job = 'teacher'

If you want to assign variables in getjob more dynamically, you could use __dict__ to get all attributes as a dictionary from the class, but then you have to ignore the extra arguments.如果您想更动态地在getjob分配变量,您可以使用__dict__从类中将所有属性作为字典获取,但是您必须忽略额外的参数。 Use ** to unpack and catch unassign keyword arguments :使用** 解包并捕获 unassign 关键字参数

class human(object):
    def __init__(self,name,age) -> None:
        self.name= name
        self.age = age
    
    ...

    def getjob(self,tfunc):
        return tfunc(**self.__dict__)

class teacher(human):
    def __init__(self,name,age, **ignore) -> None:
        super().__init__(name, age)
        self.job = 'teacher'

However, I would instead make the "job" class an attribute of a human .但是,我会让“工作”类成为一个human的属性。 This way you don't have to create a new human each time they change jobs.这样您就不必在他们每次换工作时都创建一个新人。 If you think about it, changing jobs doesn't make you a different "human instance".如果你仔细想想,换工作不会让你成为一个不同的“人类实例”。 Maybe something like:也许是这样的:

class human(object):
    def __init__(self,name,age,job=None) -> None:
        self.name= name
        self.age = age
        self.job = job

steve = human("steve", 21)
steve.job = teacher()
bob = human("bob", 50, worker())

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

相关问题 如何将变量从一个 class 传递到 Python 中的另一个变量? - How can I pass a variable from one class to another in Python? 如何从另一个类继承实例参数/方法? - How can i inherit instance parameters /methods from another class? 如何在 Python 中从一个 class 到另一个 class 调用列表? - How can a list be called from one class to another class in Python? Python:将一个类的方法分配给另一个类的实例 - Python: Assign a method from one class to an instance of another class Python 3:如何获取一个类来修改另一个类的实例中的值? - Python 3: How do I get one class to modify values in an instance of another class? 如何从列表Python创建类实例 - How can I create a class instance from a list Python 使用Python将变量从一个类实例传递给另一个实例? - Passing variable from one class instance to another using Python? 在Django中创建另一个实例后,如何更改从模型类实例派生的变量? - How can I make a variable derived from a model class instance change as soon as another instance is created in Django? 我可以将一个类的实例视为另一个类的属性 - Can I treat an instance of one class as an attribute of another 我可以动态地将一个类的实例转换为另一个类吗? - Can I dynamically convert an instance of one class to another?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM