基于用户输入的类创建自动化

时间:2020-10-02 18:44:46

标签: python class

因此在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()

基本上,有没有内置函数可以通过字符串引用类?

3 个答案:

答案 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}')