Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中使用变量作为类名?_Python_Dynamic Typing - Fatal编程技术网

在Python中使用变量作为类名?

在Python中使用变量作为类名?,python,dynamic-typing,Python,Dynamic Typing,我想知道如何在Python中为对象和函数名使用变量。在PHP中,您可以执行以下操作: $className = "MyClass"; $newObject = new $className(); 如何在Python中完成这类工作?或者,我完全不理解Python的一些基本区别,如果是的话,它是什么?在Python中 className = MyClass newObject = className() 第一行使变量className引用与MyClass相同的内容。然后,下一行通过classN

我想知道如何在Python中为对象和函数名使用变量。在PHP中,您可以执行以下操作:

$className = "MyClass";

$newObject = new $className();

如何在Python中完成这类工作?或者,我完全不理解Python的一些基本区别,如果是的话,它是什么?

在Python中

className = MyClass
newObject = className()
第一行使变量
className
引用与
MyClass
相同的内容。然后,下一行通过
className
变量调用
MyClass
构造函数

作为一个具体例子:

>>> className = list
>>> newObject = className()
>>> newObject
[]
(在Python中,
list
list
类的构造函数。)

不同之处在于,在PHP中,您将要引用的类的名称表示为字符串,而在Python中,您可以直接引用同一个类。如果必须使用字符串(例如,如果类的名称是动态创建的),则需要使用其他技术。

如果您有以下情况:

class MyClass:
    def __init__(self):
        print "MyClass"
然后你通常会这样做:

>>> x = MyClass()
MyClass
但你也可以这样做,我想你是在问:

>>> a = "MyClass"
>>> y = eval(a)()
MyClass
但是,对于使用“eval()”的字符串的位置要非常小心——如果它来自用户,那么实际上就是在创建一个巨大的安全漏洞


更新:如coleifer的回答所示,使用
type()
远远优于此解决方案。

假设某个\u模块有一个名为“class\u name”的类:

我应该注意,在这里您应该小心:如果字符串来自用户,将字符串转换为代码可能会很危险,因此在这种情况下,您应该记住安全性。:)

另一种方法(假设我们仍然使用“class_name”):


后一种方法可能是实现这一点的最安全的方法,因此如果可能的话,它可能是您应该使用的方法。

如果您需要在Python中创建一个动态类(即名称为变量的类),您可以使用type(),它包含3个参数: 名称、基数、属性

>>> class_name = 'MyClass'
>>> klass = type(class_name, (object,), {'msg': 'foobarbaz'})

<class '__main__.MyClass'>

>>> inst = klass()
>>> inst.msg
foobarbaz
>class\u name='MyClass'
>>>klass=type(类名,(对象,,{'msg':'foobarbaz'})
>>>inst=klass()
>>>仪器味精
富巴巴兹
  • 但是请注意,这不会“实例化”对象(即不调用构造函数等)。它会创建具有相同名称的新(!)类
我使用:

newObject=globals()[className]()

OMG,不!eval函数是邪恶的。不要使用它。@TimB,如果由我决定的话,我想这应该是最好的答案。我很想听听你为什么需要这样做——我想可能有一种更类似python的方法,它不需要变量类名。“我是否完全不理解Python的一些基本区别,如果是,那是什么?"可能。为什么要使用上面示例中的代码?请提供一个更大的示例,提供一些上下文。很有趣,但我同意TimB的观点,我想听听这个用例。python中没有变量,只有名称。在最近的一个例子中,我实现了一个类的两个不同子类。它们有类似的不同实现,用于相同的常规工作,它们的API大致相同。我想这是一种策略模式?无论如何,我想根据上下文动态使用其中一种。非常好,我正在为动态类和动态字段创建句柄。我做了
classes={'class1':class1,'class2':class2,…}
。现在我可以使用
myob=classes获取对象['很好,很简单的技巧。在我发现这个之前2个小时,我一直在窃听。谢谢。否决,因为你的解决方案与问题中的解决方案不匹配。他正在寻找的是一个带有字符串的类的实例化。请遵守PEP8。使用mixedCase名称感觉有点违背了它所代表的值。同意第一条评论,这不适用于f或者一个存储在变量中的类名它对OP有效,这就是为什么他接受了这个答案@Matt。它对我也有效。@reggie,他问了一个字符串,我想提出这个问题的家伙也可以用Greg Hewgill解决这个问题。因为,我们想要使用的所有类都必须已经存在,他可以将它们作为名称导入到a中使用,而不是一个随机的字符串!
class_lookup = { 'class_name' : class_name }
some_object = class_lookup['class_name']()  #call the object once we've pulled it out of the dict
>>> class_name = 'MyClass'
>>> klass = type(class_name, (object,), {'msg': 'foobarbaz'})

<class '__main__.MyClass'>

>>> inst = klass()
>>> inst.msg
foobarbaz