我是編程新手,剛剛了解了面向物件編程的概念。
我試圖找到一種方法來修改現有實體使其屬于另一個類,我的意思是繼承它的大部分屬性而不是方法。
就像我們人類得到一份新作業(方法與舊作業不同)但仍然是同一個人(保留一些財產,如年齡、姓名等)。
我不擅長描述我的問題,所以我會在這里粘貼我的示例代碼。
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個左右的回合才會回退到默認行為。
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.
What I'm seeking is something like getjob() in my example code, but with less jank.
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.
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).
I edit this because my original question is too vague and not specific.
我盡可能少改變,以更清楚地描述我想要實作的目標。我提供了一些背景,因為我希望它會有所幫助。
uj5u.com熱心網友回復:
當您有一個子類時,您可以使用super()超類 init 來避免代碼重復。此外,現在 if 陳述句introduce必須檢查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__從類中獲取所有屬性作為字典,但是您必須忽略額外的引數。使用**以解包和捕捉取消分配關鍵字引數:
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())
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/318007.html
