2014-03-25 31 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