簡體   English   中英

Python結構模式匹配 - 將對象傳遞給case語句

[英]Python Structural pattern matching - pass Object to case statement

這是我的代碼

class BasePlayer:
    @staticmethod
    def walk(direction):
        print(f"I run into {direction}")

class Archer(BasePlayer):
    @staticmethod
    def shoot():
        print("shoot")

class Wizard(BasePlayer):
    @staticmethod
    def cast_spell():
        print("Spell casted")

def play(expr):
    match expr.split():
        case [("Archer" | "Wizard") as player, "walk", ("north" | "south" | "west" | "east") as direction]:
            Archer.walk(direction)
        case ["Archer", "shoot"]:
            Archer.shoot()
        case _:
            raise Exception("Command not working...")

play("Archer walk west")

到目前為止效果很好,但我希望在第一個case語句中,我希望這樣做更通用,如下所示:

    case [(Archer | Wizard) as player, "walk", ("north" | "south" | "west" | "east") as direction]:
        player.walk(direction)

但是我不能在 case 語句中使用 Objects(模式不綁定 Archer)。 如果我將其保留為字符串,則player將不是類,而只是一個字符串。

有沒有辦法使這項工作?

首先, exprstr類型,而expr.split()產生一個str list 您需要將 match 語句的那部分更改為一個函數,該函數將生成您想要實際匹配的類型。

您將(或可能遇到)您的通用語句版本遇到的問題的第二部分是這個特定問題,其中假定裸名是要分配的變量,因此需要解決方法(請參閱答案在該線程中了解更多詳細信息)。 故障演示如下:

>>> match some_expression:
...     case [(Archer | Wizard) as player, "walk", ("north" | "south" | "west" | "east") as direction]:
...         player.walk(direction)
... 
  File "<stdin>", line 2
SyntaxError: name capture 'Archer' makes remaining patterns unreachable

作為一個快速而骯臟的答案,我將做一件懶惰的事情並將子類作為屬性分配給一個空類(以模擬導入包含這些可播放類型的模塊,例如可播放單元的unit模塊)。 應該做些什么來實現你想要的目標的核心思想可能是這樣的:

class unit():
    "pretend this is a module"

unit.Wizard = Wizard
unit.Archer = Archer

def parse(expr):
    # Parse the incoming expression to [BasePlayer, str, str, ...]
    # Defaults to BasePlayer for unknown unit type.
    r = expr.split()
    r[0] = getattr(unit, r[0], BasePlayer)
    return r

def play2(expr):          
    match(parse(expr)):  # use the above parse function to parse the expression
        case [(unit.Archer | unit.Wizard) as player, "walk", ("north" | "south" | "west" | "east") as direction]:
            player.walk(direction)
        case [unit.Archer as player, "shoot"]:
            player.shoot()
        case _:
            raise Exception("Command not working...")

試用play2功能:

>>> play2('Archer walk west')
I run into west
>>> play2('Wizard walk west')
I run into west
>>> play2('Archer shoot')
shoot
>>> play2('Wizard shoot')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 8, in play2
Exception: Command not working...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM