我正在嘗試制作基于文本的 RPG。我有一些代碼,例如:
英雄.py:
class Hero():
def __init__(self):
pass
def Attack(self, target):
# ...
def TakeDamage(self, amount):
# ...
怪物.py:
class Monster():
def __init__(self):
pass
def Attack(self, target):
# ...
def TakeDamage(self, amount):
# ...
整個檔案結構如下所示:
|__ backend
__init__.py
monsters.py
heroes.py
MainGame.py
假設我想要Monster并Hero訪問彼此的Attack功能TakeDamage,例如:
class Monster():
def __init__(self):
pass
def Attack(self, target):
# ...
def TakeDamage(self, amount, target:Hero):
damage = # damage calculation here
target.TakeDamage(damage)
我怎樣才能做到這一點?到目前為止,我已經嘗試過:
from .monsters import Monster在各自的檔案中相互匯入(例如) - 這給了我一個錯誤閱讀ImportError: cannot import name 'Monster' from partially initialized module 'backend.monsters' (most likely due to a circular import)。
uj5u.com熱心網友回復:
廣義上講,類沒有方法。實體確實如此。類的目的是定義資料型別。為了使用實體,您無需在 Python 中查看該定義。
考慮Monster類中的代碼:
def TakeDamage(self, amount, target:Hero):
damage = # damage calculation here
Hero.TakeDamage(damage)
(我暫時忽略這里的邏輯可能沒有那么大的意義。)
寫作:Hero是一種暗示——對閱讀代碼的人,也可能對第三方工具;Python 本身并不關心——這target將是Hero該類的一個實體。
我們想在那個實體上呼叫一個方法,而不是在類上。該類沒有方法TakeDamage;它只有一個TakeDamage 函式,用于在我們通過實體查找時創建方法。
因此,代碼不應該說Hero.TakeDamage(damage). 它應該說target.TakeDamage(damage),因為target是Hero我們將呼叫其方法的實體的名稱。
為此,我們不需要定義Hero類。monsters.py 不應該 import使這項作業。
當代碼運行時,在嘗試呼叫方法的那一刻,Python 會檢查被命名的事物是否target具有TakeDamage屬性。當它沒有找到直接附加到實體的物件時,它會在類中查找,并在該類中找到TakeDamage函式。它將自動從中創建一個方法。然后它會檢查TakeDamage它從這個程序中得到的那個是可呼叫的(劇透:它是,因為它是一個方法),然后呼叫它。
uj5u.com熱心網友回復:
這是我設計這款游戲的一種方式:
├── backend
│ ├── __init__.py
│ ├── character.py
│ ├── heros.py
│ └── monsters.py
└── main.py
character.py是英雄和怪物之間的共同職業。
# character.py
class Character:
def __init__(self):
self.health = 100
def attack(self, target):
target.take_damage(1)
def take_damage(self, amount):
self.health -= amount
def __repr__(self):
return (
f"{self.__class__.__name__}("
f"health={self.health!r}"
f")"
)
# heros.py
from .character import Character
class Hero(Character):
pass
# monsters.py
from .character import Character
class Monster(Character):
def attack(self, target):
target.take_damage(5)
# main.py
from backend.heros import Hero
from backend.monsters import Monster
h = Hero()
m = Monster()
h.attack(m)
m.attack(h)
print(h)
print(m)
輸出:
Hero(health=95)
Monster(health=99)
這里的關鍵發生在attack方法內部:它以數量呼叫target.take_damage()。
請注意,heros.py不匯入monsters.py,反之亦然。這樣做可能會導致回圈參考,這很混亂。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/498106.html
上一篇:PHP使用替代類(如果存在)
