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

2024-06-17 15:07:44 发布

您现在位置: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.

Some backgrounds:

I was writing a "AI" for a minigame as coding practice, I want the "AI" have very different behavior sometimes.

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.

And I want to call instance.act() inside the game loop for every "AI", instead of instance.act_default() and instance.act_defensive().

So I think that so call "polymorphism" from what I just learn fit this perfectly, then I encountered this problem.

在我的示例代码中,我所寻找的是类似于getjob()的东西,但没有太多jank

我可以想象,当类获得更多属性时,getjob()方法将变得真正的集群化和不可读,而这不是我想要的

也许不是每次人类找到新工作时都创建一个新的人类实例来替换旧的实例

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


我之所以编辑这篇文章,是因为我最初的问题太模糊,也不具体

我尽可能少的改变,来更清楚地描述我想要实现的目标。我还提供了一些背景资料,希望能有所帮助


Tags: and方法nameselfageismydef
1条回答
网友
1楼 · 发布于 2024-06-17 15:07:44

当您有一个子类时,您可以使用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__从类中获取所有属性作为字典,但是您必须忽略额外的参数。使用**unpack and catch unassign keyword arguments

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'

但是,我会将“job”类作为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())

相关问题 更多 >