因此在python中,有一个getattr
函数可以自动获取特定类的属性,这很公平。
我想做的是从用户输入中创建一个类,类似于我可以使用getattr
遍历类属性的方法。
这是我想到的过程:
# Define classes that the user could chose
class Person():
def __init__(self):
self.prop1 = 'hi'
# Define other classes
className = input() # The user would then type a class name like Person
newObj = className() # I would want this to evaluate like Person()
基本上,我试图不让我的代码看起来像一堆
if className == "Person":
newObj = Person()
elif className == "Dog":
newObj = Dog()
基本上,有没有内置函数可以通过字符串引用类?
答案 0 :(得分:1)
如果两个类的__init__
都采用相同的参数,则最简单的方法是使用映射字典。下面的示例涉及厚脸皮的错误处理,如果将第二行分成几行,则可以避免。
mapping_dict = {'Person': Person, 'Dog': Dog}
instance = mapping_dict.get(user_input, lambda: print('Invalid class name'))()
# instance is None if an invalid input was provided
没有厚脸皮的错误处理:
mapping_dict = {'Person': Person, 'Dog': Dog}
class_obj = mapping_dict.get(user_input)
if class_obj:
instance = class_obj()
else:
print('Invalid class name')
答案 1 :(得分:0)
您可以使用工厂设计模式:
class CAR(object):
def __str__(self):
return "This is a car"
class BUS(object):
def __str__(self):
return "This is a bus"
class TRAIN(object):
def __str__(self):
return "This is a train"
def create_vehicle(vehicle_type):
target_class = vehicle_type.upper()
return globals()[target_class]()
vehicles = ['bus', 'car', 'train']
for v in vehicles:
print (create_vehicle(v))
输出为:
This is a bus
This is a car
This is a train
但是,还有另一种基于元类的解决方案,对于这种简单的要求而言,这可能会显得过份。
_registry = {}
class MetaClass(type):
def __init__(cls, clsname, bases, methods):
super().__init__(clsname, bases, methods)
_registry[cls.__name__] = cls
class CAR(metaclass=MetaClass):
def __str__(self):
return "This is a car"
class BUS(metaclass=MetaClass):
def __str__(self):
return "This is a bus"
class TRAIN(metaclass=MetaClass):
def __str__(self):
return "This is a train"
def create_vehicle(vehicle_type):
target_class = vehicle_type.upper()
return _registry[target_class]()
vehicles = ['bus', 'car', 'train']
for v in vehicles:
print (create_vehicle(v))
答案 2 :(得分:-2)
下面的动态方法
import sys, inspect
def get_classes():
return {name: obj for name, obj in inspect.getmembers(sys.modules[__name__]) if inspect.isclass(obj)}
class Person():
def __init__(self):
print('Person ..')
self.prop1 = 'hi 0'
class Student():
def __init__(self):
print('Student ..')
self.prop1 = 'hi 1'
classes_mapping = get_classes()
user_input = input('Type class name:')
clazz = classes_mapping.get(user_input)
if clazz:
obj = clazz()
else:
print(f'Unknown class {user_input}')