簡體   English   中英

如何在沒有if的情況下實例化許多繼承類之一

[英]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子句,或僅使用dictget方法,例如

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.

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