根据Python中的名称列表生成类

时间:2018-07-21 13:17:54

标签: python python-3.x

该方法一开始可能是错误的,但是我正在尝试执行以下操作:

class Material:
    pass


class Vacuum(Material):
    def __str__(self):
        return 'vacuum'


class Aluminum(Material):
    def __str__(self):
        return 'aluminum'


class Graphite(Material):
    def __str__(self):
        return 'graphite'


class Beryllium(Material):
    def __str__(self):
        return 'beryllium'

我有处理不同材料的不同代码。与其将字符串作为参数传递给其他部分,不如给它对象。这样可以使用ipython来完成制表符补全,这也是一种强制类型的方法。

为避免更改已写的内容,它们只会做str(argument):如果是字符串,它将恢复旧的行为,如果它是将起作用的对象之一。

现在的问题是:我想支持给定的材料清单:

allowed_materials = ['vacuum', 'aluminum', 'graphite',]

,该列表可能正在增长。与其手动编写类,不如如何基于列表生成它们?

3 个答案:

答案 0 :(得分:1)

如果对于不同的材料不需要不同的类名,则只需在材料类内部对其进行初始化。如果没有,我将删除答案。

class Material:
    def __init__(self,name):
        self.name=name
    def __str__(self):
        return self.name

allowed_materials = ['vacuum', 'aluminum', 'graphite',]

obj_lst=[Material(material) for material in allowed_materials]

for obj in obj_lst:
    print(str(obj))

输出:

vacuum
aluminum 
graphite

答案 1 :(得分:1)

您可以定义一个可以为您生成类的元类。

class mattype(type):
    def __new__(mcls, name, bases=(), d=None):
        def __str__(self):
            return name.lower()
        if not d:
            d = {}
        d['__str__'] = __str__
        bases = (*bases, Material)
        return super().__new__(mcls, name.title(), bases, d)

allowed_materials = ['vacuum', 'aluminum', 'graphite',]
classes = {name: mattype(name) for name in allowed_materials}
str(classes['vacuum']())
# 'vacuum'

答案 2 :(得分:1)

我最终完成了以下操作,还向模块添加了对象。

import sys


class Material:
    def __str__(self):
        return self.__class__.__name__

    pass


print(sys.modules[__name__])

_materials = ['Copper', 'Vacuum']

for m in _materials:
    setattr(sys.modules[__name__], m, type(m, (Material,), {})())