首页 > 解决方案 > 如何使用 exec() 在函数内部创建一个类?

问题描述

我正在创建一个函数,它在其中创建一个类并返回它......

    def create_object(**objects):
        # creates class, NewClass
        class NewClass:
            pass
        for key in objects.keys():
            # creating objects in NewClass
            exec("NewClass.%s = %s" % (key, objects[key]))
        return NewClass

当我们调用这个函数时,

new_object = create_object(first_name='Mayank', last_name='Tyagi')
new_object.first_name

这工作正常并提供输出

>>> 'Mayank'

但我想创建一个函数,该函数将创建一个具有变量名的类。例如

    def object(class_name, **objects):
        # create a class where the value of class_name is the name of class
        exec("class %s:\n\tpass" % (class_name))
        for key in objects.keys():
            # creating new objects in this class
            exec("NewClass.%s = %s" % (key, objects[key]))

并在调用该函数后,

object('ClassName', first_name='Mayank', last_name='Tyagi')
ClassName.first_name

它应该给出输出,

>>>'Mayank'

这个怎么做?

-带着希望寻求帮助:)

标签: pythonpython-3.xoop

解决方案


不要使用 exec ,除非你绝对必须这样做,而你没有。

利用type

def __init__(self, first, last):
    self.first = first
    self.last = last

cls_ = type("Mayank", (object,), dict(__init__=__init__))

obj = cls_("Mayank","Tyagi")

print(obj, vars(obj))

出去:

<__main__.Mayank object at 0x1028050b8> {'first': 'Mayank', 'last': 'Tyagi'}

编辑:来自帕特里克的评论:该词典中第三个参数的任何type内容都是类级属性。我假设 OP 想要创建一个类的实例,该类具有他们想要在实例级别存储名称的 first 和 lastname 实例级属性。因此允许不同的 Mayank 实例具有不同的名称。当然,它们可能意味着具有名字和名称的类,设置为 Mayank/Tyagi 的类级别。在这种情况下,这些将直接传递到该 dict 中,而不是提供 init 函数。

微妙:即使是类级别的名字和姓氏也允许实例级别的覆盖:

m1 = Mayank()
m2 = Mayank()
m3 = Mayank()

m1.last = "Foo"
m2.last = "Bar"

当分配发生在实例级别时,打印 m1、m2、m3 的姓氏将分别打印 Foo、Bar、Mayank,而不会更改类。


推荐阅读