繁体   English   中英

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

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

我是编程新手,刚刚了解了面向对象编程的概念。

我试图找到一种方法来修改现有实例使其属于另一个类,我的意思是继承它的大部分属性而不是方法。

就像我们人类得到一份新工作(方法与旧工作不同)但仍然是同一个人(保留一些财产,如年龄、姓名等)。

我不擅长描述我的问题,所以我会在这里粘贴我的示例代码。

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()

输出将是:

> 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.

一些背景:

我正在为小游戏编写“AI”作为编码练习,我希望“AI”有时具有非常不同的行为。

比如当受到一定程度的伤害时变成防御性的,有不同的动作,根本不考虑攻击,只有10个左右的回合才会回退到默认行为。

我想在游戏循环中为每个“AI”调用 instance.act(),而不是 instance.act_default() 和 instance.act_defensive()。

所以我认为我刚刚学到的所谓的“多态性”非常适合这个,然后我遇到了这个问题。

我正在寻找类似于我的示例代码中的 getjob() 的东西,但卡顿更少。

我想当类获得更多属性时, getjob() 方法将变得非常聚集且不可读,这不是我想要的。

并且可能不会在人类每次获得新工作时创建一个新的人类实例来替换旧的人类实例。

也许而不是a = a.getjob(teacher)在 getjob() 方法中使用类似a.getjob(teacher)self = tfunc(self.name,self.age)东西(我尝试过但不起作用)。


我编辑这个是因为我原来的问题太模糊而且不具体。

我尽可能少改变,以更清楚地描述我想要实现的目标。 我提供了一些背景,因为我希望它会有所帮助。

当您有一个子类时,您可以使用super()来使用超类 init 以避免代码重复。 此外,现在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'

如果您想更动态地在getjob分配变量,您可以使用__dict__从类中将所有属性作为字典获取,但是您必须忽略额外的参数。 使用** 解包并捕获 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'

但是,我会让“工作”类成为一个human的属性。 这样您就不必在他们每次换工作时都创建一个新人。 如果你仔细想想,换工作不会让你成为一个不同的“人类实例”。 也许是这样的:

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.

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