[英]How to Instantiate One of Many Inheriting Classes Without if
比如說我有一些類,它們都是同一個父類所固有的,並且具有相同的參數。 一個常見的例子;
class Pet():
...
class Cat(Pet):
__init__(self,name,colour):
Pet.__init__(self,name,colour)
....
class Cactus(Pet):
__init__(self,name,colour):
Pet.__init__(self,name,colour)
....
然后說我想稍后根據用戶輸入在程序中實例化某種寵物。 首先我會想到的是;
if(pet_type == 'Cat'):
animal = Cat(name,colour)
elif(pet_type == 'Cactus'):
animal = Cactus(name,colour)
etc...
但是,有沒有不需要if的更好的方法呢? 例如,如果該程序被開發為包括超過1000只全部來自寵物的動物,那么它就不是feasilbe。
創建允許的類的字典:
classes = {
'Cat': Cat,
'Cactus': Cactus,
}
try:
cls = classes[pet_type]
except KeyError:
# handle invalid pet_type here
else:
animal = cls(name, colour)
根據您對KeyError
的響應,您可能需要使用finally
子句而不是else
子句,或僅使用dict
的get
方法,例如
animal = classes.get(pet_type, Pet)(name, colour)
您尋找的東西被稱為工廠模式。 有很多方法可以實現此目的,從顯示它們的顯式if-cascades到元類魔術。
一個非常簡單的方法是類裝飾器:
PET_CLASSES = {}
def pet_class(cls):
PET_CLASSES[cls.__name__.lower()] = cls
def create_pet(name):
return PET_CLASSES[name.lower()]()
@pet_class
class Cat:
pass
@pet_class
class Dog:
pass
print(create_pet("dog"))
您可以使用getattr()
通過其字符串名稱獲取類。
my_class = getattr(module, "class_name")
接着
my_object = my_class(...)
可以通過module = __import__("module_name")
訪問模塊對象
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.