关于python:如何动态创建类

How to dynamically create classes

我对python比较陌生,我在问自己是否可以在函数中动态创建名称的类?

代码:

1
2
3
4
5
6
7
def create_dummy_elements():
    rows = [A,B,C,D,E,F,G,H,I]
    columns = [A,B,C,D,E,F,G,H,I]

    for r in range (rows):
        for c in range (columns):
            ***** = element(1,1,1,False)

我的结果应该是类"element"的81个对象,比如aa、ab、ac、ad……*是我真正想要的…


我认为你可以按照FarmerJoe的建议创建一个列表,但是如果你真的想向Global添加名称空间,你可以这样做

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class element(object):
    def __init__(self, *args):
        self._args = args
    def __repr__(self):
        return ' '.join(map(str, self._args))


rows = ['A','B']
columns = ['A','B']

for r in rows:
    for c in columns:
        exec('%s%s = element(r,c,False)' % (r,c))

print AB

输出将是

1
A B False


您可以列出这些对象,但动态创建变量名并不理想。

像这样:

1
2
3
4
my_list_of_elements = []
for r in range (rows):
    for c in range (columns):
        my_list_of_elements.append(element(1,1,1,False))

然后您可以通过索引号访问它们,例如:my_list_of_elements[n]

或者为了匹配循环的二维样式,您可以:

1
2
3
4
5
6
my_list_of_elements = []
for r in range (rows):
    temp = []
    for c in range (columns):
        temp.append(element(1,1,1,False))
    my_list_of_elements.append(temp)

然后可以执行my_list_of_elements[i][j]访问第i行和第j列。

如果您喜欢字符串索引,字典会很好地为您服务:

1
2
3
4
my_dict_of_elements = {}
for r in range (rows):
    for c in range (columns):
        my_dict_of_elements["element"+(r*c+c)] = element(1,1,1,False)

例如,它可以让您像这样访问my_dict_of_elements["element0"]

正如Atomicinf在本文的评论中所提到的,您可以使用globals()dict,但似乎我们都同意有更好的实践。


尽管可以在Python中动态地创建类和类的命名实例,但通常不赞成这样做。把这些东西的集合存储在某种类型的容器(如列表或字典)中,然后在必要时通过索引或键访问它们,这被认为是更"Python式"和更优雅的方式。以下是如何应用于您的问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Element(object):
    def __init__(self, name, a=None, b=None, c=None):
        self.name, self.a, self.b, self.c = name, a, b, c
    def __str__(self):
        classname = self.__class__.__name__
        return('{classname}('
               'name={self.name}, b={self.a}, '
               'c={self.b}, d={self.c})'.format(classname=classname,
                                                self=self))
board = {}  # empty dictionary
for row in 'ABCDEFGHI':
    for col in 'ABCDEFGHI':
        name = row+col
        board[name] = Element(name)  # assign a named Element instance

# sample usage
board['AB'].a = 42
print board['AB']  # Element(name=AB, a=42, b=None, c=None)
board['GD'].c = 'something'
print board['GD']  # Element(name=GD, a=None, b=None, c=something)

注:我不知道如何调用Element类的大部分属性,所以只是使用上面的abc进行说明。