python如何用字符串实例化类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python如何用字符串实例化类相关的知识,希望对你有一定的参考价值。

在python中

a = 'obj'
class obj:
pass

如何利用变量a来实例化这个名为obj的class

参考技术A 反射机制吧?其实直接用 globals() 这个函数就可以了,他可以返回所有全局对象的列表:
>>> globals()
'a': 'obj', 'obj': <class '__main__.obj'>, '__builtins__': <module 'builtins' (
built-in)>, '__package__': None, '__name__': '__main__', '__doc__': None

所有直接对这个列表索引就可以获得类了。
>>> globals()[a]
<class '__main__.obj'>
>>> globals()[a]()
<__main__.obj object at 0x00E5A350>本回答被提问者采纳
参考技术B a = 'obj'
class obj :
def __init__( self ):
self.name = 'obj'
print self.name

b = None

exec( 'b = %s()'%a )
print b

python实例化类,数据混乱串内容问题(可变类型属性的初始化)

一般情况下,我们知道 在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象

当把list和dict当参数传入函数时,强制为引用传值(即:在函数内部修改了对象,函数外部的对象也会改变)

def update_remark(data):
    print(\'函数里修改了remak为:已修改\')
    data[\'remark\'] = \'已修改\'
    return data[\'remark\']


dict1 = {\'remark\': \'测试\'}
print(\'外面里remark:\', end=\' \')
print(dict1)

update_remark(dict1)

print(\'外面里remark:\', end=\' \')
print(dict1)

执行结果如下:

 

这个问题也不大,写函数的时候注意一下就好了。


 

问题是:一个类实例化出两个对象,修改各自对象的属性,数据还能被引用了?? 

 

测试代码如下:

class Demo:
    name = \'\'
    data = {}

    def __init__(self):
        pass

    def set_name(self, name):
        self.name = name

    def get_name(self):
        return self.name

    def set_data(self, key, value):
        self.data[key] = value

    def get_data(self, key):
        return self.data[key] if key in self.data else None


if __name__ == \'__main__\':
    obj1 = Demo()
    obj2 = Demo()

    print(obj1)
    print(obj2)

    obj1.set_name(\'实例1\')
    obj2.set_name(\'实例2\')

    print(obj1.get_name())
    print(obj2.get_name())

    obj1.set_data(\'remark\', \'测试\')

    print(obj1.get_data(\'remark\'))
    print(obj2.get_data(\'remark\'))

执行结果如下:

 

这下就头大了,我只修改了obj1对象里的 data 属性,为何 obj2 里的 data 属性也跟着变了??

实例化对象之后,可变类型的属性居然还是引用传值的??

 


 

解决办法:不要直接在类的顶部里初始化属性,在构造方法里初始化属性才不会出错

类顶部的属性可以直接不写,在 __init__ 构造函数里用"self.属性名 = 属性值" 这种方式设置类的属性就可以了

注:强迫症一定要在类的顶部写属性的话,__init__ 里也还重新初始化一下

修改后的类如下:

class Demo:
    def __init__(self):
        self.name = \'\'
        self.data = {}

    def set_name(self, name):
        self.name = name

    def get_name(self):
        return self.name

    def set_data(self, key, value):
        self.data[key] = value

    def get_data(self, key):
        return self.data[key] if key in self.data else None


if __name__ == \'__main__\':
    obj1 = Demo()
    obj2 = Demo()

    print(obj1)
    print(obj2)

    obj1.set_name(\'实例1\')
    obj2.set_name(\'实例2\')

    print(obj1.get_name())
    print(obj2.get_name())

    obj1.set_data(\'remark\', \'测试\')

    print(obj1.get_data(\'remark\'))
    print(obj2.get_data(\'remark\'))

执行结果如下:

 


 

不知道是Python的bug还是本来就是这样设计的,总之:引以为戒!!

 

以上是关于python如何用字符串实例化类的主要内容,如果未能解决你的问题,请参考以下文章

实例化类的 Python3 问题

在 Python 中导入后自动实例化类

Python 在类定义中实例化类

在 Python 中实例化类的区别

在实例化类之前在 Python 类中定义的方法的正确术语是啥?

如何正确模拟实例化类变量的函数?