我想match根據一個類來確定要執行的操作type。我似乎無法弄清楚該怎么做。我知道他們是實作這一目標的其他方式,我只是想知道可以這樣做。我不是在尋找有很多解決方法。
class aaa():
pass
class bbb():
pass
def f1(typ):
if typ is aaa:
print("aaa")
elif typ is bbb:
print("bbb")
else:
print("???")
def f2(typ):
match typ:
case aaa():
print("aaa")
case bbb():
print("bbb")
case _:
print("???")
f1(aaa)
f1(bbb)
f2(aaa)
f2(bbb)
輸出如下:
aaa
bbb
???
???
uj5u.com熱心網友回復:
嘗試在行中使用typ()而不是:typmatch
class aaa():
pass
class bbb():
pass
def f1(typ):
if typ is aaa:
print("aaa")
elif typ is bbb:
print("bbb")
else:
print("???")
def f2(typ):
match typ():
case aaa():
print("aaa")
case bbb():
print("bbb")
case _:
print("???")
f1(aaa)
f1(bbb)
f2(aaa)
f2(bbb)
輸出:
aaa
bbb
aaa
bbb
更新:
根據 OP 的評論,要求提供比問題中的示例類更普遍地適用于類的解決方案,這里有一個解決這個問題的答案:
class aaa():
pass
class bbb():
pass
def f1(typ):
if typ is aaa:
print("aaa")
elif typ is bbb:
print("bbb")
else:
print("???")
def f2(typ):
match typ.__qualname__:
case aaa.__qualname__:
print("aaa")
case bbb.__qualname__:
print("bbb")
case _:
print("???")
f1(aaa)
f1(bbb)
f2(aaa)
f2(bbb)
輸出:
aaa
bbb
aaa
bbb
更新#2:
基于這篇文章和對 PEP 364 的閱讀,我創建了一個示例,展示了如何使用一些資料型別(Python 內置、集合模塊中的類和用戶定義的類)match來根據型別別(或更一般地,資料型別)確定要執行的操作:
class bbb:
pass
class namespacing_class:
class aaa:
pass
def f1(typ):
if typ is aaa:
print("aaa")
elif typ is bbb:
print("bbb")
else:
print("???")
def f2(typ):
match typ.__qualname__:
case aaa.__qualname__:
print("aaa")
case bbb.__qualname__:
print("bbb")
case _:
print("???")
def f3(typ):
import collections
match typ:
case namespacing_class.aaa:
print("aaa")
case __builtins__.str:
print("str")
case collections.Counter:
print("Counter")
case _:
print("???")
'''
f1(aaa)
f1(bbb)
f2(aaa)
f2(bbb)
'''
f3(namespacing_class.aaa)
f3(str)
import collections
f3(collections.Counter)
輸出:
aaa
str
Counter
正如另一篇文章中的答案所述:
A variable name in a case clause is treated as a name capture pattern. It always matches and tries to make an assignment to the variable name. ... We need to replace the name capture pattern with a non-capturing pattern such as a value pattern that uses the . operator for attribute lookup. The dot is the key to matching this a non-capturing pattern.
In other words, if we try to say case aaa: for example, aaa will be interpreted as a name to which we assign the subject (typ in your code) and will always match and block any attempts to match subsequent case lines.
To get around this, for class type names (or names generally) that can be specified using a dot (perhaps because they belong to a namespace or another class), we can use the dotted name as a pattern that will not be interpreted as a name capture.
For built-in type str, we can use case __builtins__.str:. For the Counter class in Python's collections module, we can use case collections.Counter:. If we define class aaa within another class named namespacing_class, we can use case namespacing_class.aaa:.
However, if we define class bbb at the top level within our Python code, it's not clear to me that there is any way to use a dotted name to refer to it and thereby avoid name capture.
type有可能有一種方法可以在一行中指定一個用戶定義的類,case而我還沒有弄清楚。否則,能夠為點表型別而不是非點表型別執行此操作似乎相當隨意(而且不幸)。
uj5u.com熱心網友回復:
你想匹配一個常數值。這是常量值模式的情況:
match typ:
case somemodule.ClassOne:
...
case anothermodule.ClassTwo:
...
常量值模式必須采用以下形式NAME ('.' NAME) - 即,一個名稱后跟至少一個屬性查找。裸名將被視為捕獲模式。這對于在其他模塊中定義的類來說很好,但是如果你想匹配同一個模塊中的類,你可以匯入當前模塊:
# in somemodule.py
import somemodule
class ClassOne:
...
class ClassTwo:
...
match typ:
case somemodule.ClassOne:
...
case somemodule.ClassTwo:
...
或者如果你想避免回圈匯入,你可以創建一個命名空間:
import types
options = types.SimpleNamespace()
options.ClassOne = ClassOne
options.ClassTwo = ClassTwo
match typ:
case options.ClassOne:
...
case options.ClassTwo:
...
請注意,如果您走“匯入當前模塊”路線,則需要注意 Python 的奇怪之處,即入口點腳本被視為__main__模塊,而不管其檔案名如何。如果你這樣做python somefile.py并嘗試import somefile在其中,它將作為模塊執行第二次運行并創建所有類的第二個副本,并且你的匹配陳述句將不起作用。somefile.pysomefile
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/442676.html
上一篇:在類內的另一個函式中使用變數
下一篇:XSLT-如何編輯多個子元素
