2014-03-25 34 views
2

我使用globals()來即時創建類的實例。使用全局變量()創建類實例

例如,

animals.py

class Cat(): 
    pass 

class Dog(): 
    pass 

test.py

#import animals 

def create_animal(): 
    # Take 'which_animal' input from 
    # somewhere in form of string 
    try: 
    animal1 = globals()[which_animal]() 
    catch: 
    . 
    . 

我這樣做是爲了避免長的if-else階梯。
這種方法有什麼優點和缺點?
是否有任何替代方法相同?
它是否構成安全威脅?

回答

3

任何您的全局變量中的名稱是可訪問的;這包括create_animal()函數以及您可能導入的任何內容。

這確實意味着可能是安全風險,具體取決於導入的內容。你應該,最起碼,過濾的__module__屬性中找到的對象:

animal_cls = globals()[which_animal] 
if animal_cls.__module__ != __name__: 
    raise TypeError('Not a class defined in this module!') 
animal1 = animal_cls() 

另一種方法是把你想在某些類型的數據結構的訪問類。你可以使用一個新的字典:

animals = { 
    'Cat': Cat, 
    'Dog': Dog, 
} 

你可以在每個類註冊自己(通過裝飾)到這樣的映射:

animals = {} 

def registered(cls): 
    animals[cls.__name__] = cls 
    return cls 

@registered 
class Cat(): 
    pass 

@registered 
class Dog(): 
    pass 

或者你可以使用一個基類; __subclasses__()方法然後讓你列出任何派生類和所有派生類:

class Animal(object): 
    pass 

class Cat(Animal): 
    pass 

class Dog(Animal): 
    pass 

animals = {cls.__name__: cls for cls in Animal.__subclasses__()} 
+0

Python3現在獨佔?或者只是決定做一箇舊式的課程,以獲得樂趣? :-)(或者按照我認爲的OP代碼) – mgilson

+0

@mgilson:在那裏,明確了對象的基礎。 :-) –

+0

謝謝,我現在對生活感覺更好:-) – mgilson