Python中根据字符串初始化类
Python在算法类code中,一个非常常见的模式是读取配置,根据配置的字符串决定应该使用哪个类,即需要解决根据类名生成实例。在这个过程中,希望能够支持使用者添加自己的类,而不需要动框架代码,典型的工厂模式。
在具体到python的实现时,需要能够根据string来决定生成哪个实例,查了几种方法:
方法一:通过getattr(module_name, class_name)来生成实例,
方法二:通过eval(class_name)来生成实例,问题主要在于eval不安全
最后采用了方法一,代码如下:
factory.py
import pizza
class PizzaFactory():
"""
Pizza factory
"""
def __init__(self):
"""
初始化
"""
pass
def create_pizza(self, module_name, name):
"""
根据name,生成对应的pizza
"""
module = __import__(module_name)
pizza_class = getattr(module, name)
return pizza_class()
class PizzaStore():
"""
pizza store
"""
def __init__(self):
self._factory = PizzaFactory()
def order_pizza(self, module_name, name):
pizza = self._factory.create_pizza(module_name, name)
print pizza
pizza.make()
pizza.box()
def read_conf(filename):
names = []
try:
with open(filename, "r") as f:
for line in f:
module_name, class_name = line.rstrip().split()
names.append((module_name, class_name))
except IOError:
sys.stderr.write("Can not find file [%s]\n" %(filename))
return names
def main():
"""
main function
"""
pizza_store = PizzaStore()
names = read_conf("pizza_conf")
for (module_name, class_name) in names:
pizza_store.order_pizza(module_name, class_name)
if __name__ == "__main__":
main()
pizza.py
class Pizza():
"""
pizza
"""
def make(self):
print "I am making"
def box(self):
print "I am boxing"
king_pizza.py
import pizza
class KingPizza(pizza.Pizza):
def __init__(self):
self._name = "My name is KingPizza"
print self._name
queen_pizza.py
import pizza
class QueenPizza(pizza.Pizza):
def __init__(self):
self._name = "My name is QueenPizza"
print self._name
pizza_conf
king_pizza KingPizza
queen_pizza QueenPizza
Tags: