python 3:类"模板"(返回参数化类的函数)

max*_*max 16 python class-design factory-pattern python-3.x

我正在尝试创建一个传递参数x并返回一个新类的函数C.C应该是固定基类的子类A,只有一个加法:添加某个类属性并设置为相等x.

换一种说法:

class C(A):
  C.p = x # x is the parameter passed to the factory function
Run Code Online (Sandbox Code Playgroud)

这很容易吗?我应该注意哪些问题?

Gle*_*ard 15

首先,请注意术语"类工厂"在Python中有点过时了.它用于像C++这样的语言,用于返回类的动态类型实例的函数.它有一个名字,因为它在C++中脱颖而出; 这种情况并不罕见,但为模式命名是很有用的.然而,在Python中,这是不断完成的 - 这是一个基本的操作,任何人都不会再给它一个特殊的名字了.

另请注意,类工厂返回类的实例 - 而不是类本身.(同样,那是因为它来自像C++这样的语言,它们没有返回只有类的对象的概念.)但是,你说你想要返回"新类",而不是类的新实例.

创建一个本地类并返回它是微不足道的:

def make_class(x):
    class C(A):
        p = x
    return C
Run Code Online (Sandbox Code Playgroud)


mgi*_*uca 8

类型函数具有3个参数的版本,它动态地构造一个新的类.传递名称,基础和包含类的属性和方法的字典.

在你的情况下:

def class_factory(x):
    return type("C", (A,), {"p": x})
Run Code Online (Sandbox Code Playgroud)

您可以显然动态设置类的名称" C",但请注意,为了使类可公开访问,您还需要将函数的结果分配给变量.你可以动态地使用globals()["C"] = ...,或者将类分配给字典,无论如何.

  • Python中的所有类都是动态创建的; 我没有理由使用特殊的低级函数来创建一个类,而不是以正常的,可以立即理解的Python方式声明一个类.此函数用于不能使用普通Python语法的地方; 例如,如果您有一个基类数组,或者是以编程方式创建类的名称. (3认同)
  • @max 不,不会有名称冲突。请注意,一个类实际上有两个单独的“名称”:类内部的名称和分配给它的变量的名称。这两个通常是相同的,但是如果你写了 "`X = type("Y", ...)`" 那么 Y 将是内部名称,X 将是变量名称。变量名称可能会发生冲突,但您可以拥有任意数量的类,这些类在内部将自己视为“C”。 (2认同)