从给定字符串动态创建类实例并在字典中保存深层副本

时间:2016-06-08 13:38:35

标签: python python-3.x

我想从一组给定的字符串中动态创建多个类实例(已复制),并坚持使用它。

这是我的方法:

# -*- coding: utf-8 -*-


# I have an number of different classes
class FourLegs:
    def __init__(self, name, age):
        self.name = name
        self.age = age


class TwoOrNoLegs:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# And only the class name and some attributes (normally in a big CSV file)
dc = dict(zip(range(0, 5), [('FourLegs', 'Dog', 11),
                            ('TwoOrNoLegs', 'Chicken', 22),
                            ('FourLegs', 'Cat', 33),
                            ('FourLegs', 'Mice', 44),
                            ('TwoOrNoLegs', 'Snake', 55)]))


# And want to create different objects depending on the given class name
# and attributes an store them in a dict
zoo = {}
for k, v in dc.items():
    an = eval(v[0])
    an.name = v[1]
    an.age = v[2]
    print(an, an.name, an.age)
    zoo[an.name] = an

for k, v in zoo.items():
    print(k, v.name, v.age)

提供:

<class '__main__.FourLegs'> Dog 11
<class '__main__.TwoOrNoLegs'> Chicken 22
<class '__main__.FourLegs'> Cat 33
<class '__main__.FourLegs'> Mice 44
<class '__main__.TwoOrNoLegs'> Snake 55
Snake Snake 55
Mice Mice 44
Dog Mice 44
Cat Mice 44
Chicken Snake 55

因为我正在使用(eval()),它似乎只创建了实例的引用(而且没有副本)。

我想要生成的结果(如果我手动创建实例,那么结果如下):

<class '__main__.FourLegs'> Dog 11
<class '__main__.TwoOrNoLegs'> Chicken 22
<class '__main__.FourLegs'> Cat 33
<class '__main__.FourLegs'> Mice 44
<class '__main__.TwoOrNoLegs'> Snake 55
Snake Snake 55
Mice Mice 44
Dog Dog 11
Cat Cat 33
Chicken Chicken 22

我真的被困在这里,很高兴每一个提示!

对于基于字符串的动态创建实例,有没有办法实现这一点?

1 个答案:

答案 0 :(得分:2)

您没有创建实例,而是直接在类上设置属性。因为您每次都在更改相同的两个类上的属性,所以您会看到在这两个类的属性中反映的最后一个值。

致电您的班级,传递姓名和年龄:

for k, v in dc.items():
    an = eval(v[0])(v[1], v[2])
    print(an, an.name, an.age)
    zoo[an.name] = an

你应该尽量避免在这里使用eval();将您的类放在字典中并将其用作查找,或使用globals()字典(但请注意,这也可以调用其他全局变量):

classes = {'FourLegs': FourLegs, 'TwoOrNoLegs': TwoOrNoLegs}

for k, v in dc.items():
    clsname, name, age = v
    an = classes[clsname](name, age)
    print(an, an.name, an.age)
    zoo[an.name] = an