你能在 python 中循环制作 类 吗?
Can you make classes in a loop in python?
我有一种情况,我正在制作一堆 classes,其中一堆实际上基本相同,所以我想循环制作它们。它们与注册系统一起使用,因此在 USAGE 方面没有问题,但我不确定如何使用确定 class 名称的变量实际定义 class...
简单示例:
classList = ['foo', 'bar', 'baz']
for className in classList:
class {{{className}}}_calc(BaseCalc):
def __init__ (self, dataFrame):
self.column = dataFrame[className]
def calc ():
return self.column.sum()
显然,这是一个非常简化的案例。我无法将参数更改为 init,因为已经存在一大堆这些参数,它们是更大结构的一部分。
该示例的其余部分使用 pandas 语法,只是为了了解它是如何使用的...但它实际上是与 SQL 数据库一起使用的,而且很多更复杂……我只是不想为“你一开始为什么要这样做?”辩护。我有充分的理由,就这样吧。
classname 在 class 行的 {{{ }}} 中,表示它是一个变量,实际上在语法上并不正确。问题是“我如何表示我使用 {{{ }}} 的目的?”我觉得。
答案可能是 metaclasses,但我仍然不确定如何为我的 class 变量命名....
预计到达时间:尝试使用@python_user 答案:
classList = ['foooo', 'bar', 'baaz']
class Base ():
def __init__ (self, buq):
self.buq = buq
def getBuq(self):
return 'buq: ' + self.buq
for cls in classList:
class TEMP(Base):
className = cls
def __init__ (self):
self.qux = len(cls)
Base.__init__(self, cls)
def blee(self, inpt):
return inpt+ self.qux
TEMP.__name__ = f'{cls}'
TEMP.__qualname__ = f'{cls}'
globals()[cls] = TEMP
f = foo()
f.getBuq()
>>>> 'buq: baaz'
这只会给我带来麻烦 class。三个人都在胡闹……我是不是在做一些很蠢的事情?
但是,您可以使用 type 函数来创建这样的动态 classes。 names = ['name1', 'name2'] 假设你必须在 python 中创建 10 个 class 对象,并用它们做一些事情,比如: obj_1 = MyClass( ) other_object.
希望能帮到你。
好吧,有一种使用“exec()”函数执行此操作的混乱方法,该函数接受任何字符串并执行它;然后你可以将你的 类 构建为一个字符串和 运行 。这是构建您的 类 的示例,您可以通过查看最后打印的全局命名空间来看到它们是声明的。
classList = ['foo', 'bar', 'baz']
class BaseCalc():
def __init__ (self, dataFrame):
self.column = dataFrame[className]
def calc ():
return self.column.sum()
for className in classList:
template = '''class %s_calc(BaseCalc):
def __init__ (self, dataFrame):
self.column = dataFrame[className]
def calc ():
return self.column.sum()''' % className
exec(template)
print(globals())
你可以这样做,使用 globals()
classList = ['foo', 'bar', 'baz']
for className in classList:
class Temp:
def __init__ (self, dataFrame):
self.column = dataFrame[className]
def calc ():
return self.column.sum()
Temp.__name__ = className
globals()[className] = Temp
然后您可以执行 foo()
来创建 class foo
的对象。对于实际示例,您必须调用 __init__
方法所需的参数。这只是为了证明它有效。
print(type(foo()).__name__) # foo
print(type(bar()).__name__) # bar
print(type(baz()).__name__) # baz
如果你想更改你的class名字,那么你可以
Temp.__name__ = f'{className}_calc'
globals()[f'{className}_calc'] = Temp
正如 wim 在评论中指出的,您还需要设置 __qualname__
。 Temp.__qualname__ = f'{className}_calc'
编辑:
由于 class 的方法中的名称查找是在运行时(而非编译时)执行的,因此代码片段存在一个错误。 className
将始终引用 classList
中的最后一个元素(在本例中为 baz
),此名称存在于循环范围之外,并将成为 className
的值在所有 classes 的方法中。 (例如:self.column = dataFrame[className]
)。 <--- 这总是 dataFrame['baz']
要解决此问题,必须声明一个名为 className
的 class 级别变量,并将 className
(循环中的变量)分配给它。所以在编译时这个值将被绑定到 class。 class 的方法中对 className
的所有引用都需要更改为 self.className
才能使代码按预期工作。
class Temp:
className = className # note this line
def __init__ (self, dataFrame):
self.column = dataFrame[self.className] # and this line with the original snippet
我有一种情况,我正在制作一堆 classes,其中一堆实际上基本相同,所以我想循环制作它们。它们与注册系统一起使用,因此在 USAGE 方面没有问题,但我不确定如何使用确定 class 名称的变量实际定义 class...
简单示例:
classList = ['foo', 'bar', 'baz']
for className in classList:
class {{{className}}}_calc(BaseCalc):
def __init__ (self, dataFrame):
self.column = dataFrame[className]
def calc ():
return self.column.sum()
显然,这是一个非常简化的案例。我无法将参数更改为 init,因为已经存在一大堆这些参数,它们是更大结构的一部分。
该示例的其余部分使用 pandas 语法,只是为了了解它是如何使用的...但它实际上是与 SQL 数据库一起使用的,而且很多更复杂……我只是不想为“你一开始为什么要这样做?”辩护。我有充分的理由,就这样吧。
classname 在 class 行的 {{{ }}} 中,表示它是一个变量,实际上在语法上并不正确。问题是“我如何表示我使用 {{{ }}} 的目的?”我觉得。
答案可能是 metaclasses,但我仍然不确定如何为我的 class 变量命名....
预计到达时间:尝试使用@python_user 答案:
classList = ['foooo', 'bar', 'baaz']
class Base ():
def __init__ (self, buq):
self.buq = buq
def getBuq(self):
return 'buq: ' + self.buq
for cls in classList:
class TEMP(Base):
className = cls
def __init__ (self):
self.qux = len(cls)
Base.__init__(self, cls)
def blee(self, inpt):
return inpt+ self.qux
TEMP.__name__ = f'{cls}'
TEMP.__qualname__ = f'{cls}'
globals()[cls] = TEMP
f = foo()
f.getBuq()
>>>> 'buq: baaz'
这只会给我带来麻烦 class。三个人都在胡闹……我是不是在做一些很蠢的事情?
但是,您可以使用 type 函数来创建这样的动态 classes。 names = ['name1', 'name2'] 假设你必须在 python 中创建 10 个 class 对象,并用它们做一些事情,比如: obj_1 = MyClass( ) other_object.
希望能帮到你。
好吧,有一种使用“exec()”函数执行此操作的混乱方法,该函数接受任何字符串并执行它;然后你可以将你的 类 构建为一个字符串和 运行 。这是构建您的 类 的示例,您可以通过查看最后打印的全局命名空间来看到它们是声明的。
classList = ['foo', 'bar', 'baz']
class BaseCalc():
def __init__ (self, dataFrame):
self.column = dataFrame[className]
def calc ():
return self.column.sum()
for className in classList:
template = '''class %s_calc(BaseCalc):
def __init__ (self, dataFrame):
self.column = dataFrame[className]
def calc ():
return self.column.sum()''' % className
exec(template)
print(globals())
你可以这样做,使用 globals()
classList = ['foo', 'bar', 'baz']
for className in classList:
class Temp:
def __init__ (self, dataFrame):
self.column = dataFrame[className]
def calc ():
return self.column.sum()
Temp.__name__ = className
globals()[className] = Temp
然后您可以执行 foo()
来创建 class foo
的对象。对于实际示例,您必须调用 __init__
方法所需的参数。这只是为了证明它有效。
print(type(foo()).__name__) # foo
print(type(bar()).__name__) # bar
print(type(baz()).__name__) # baz
如果你想更改你的class名字,那么你可以
Temp.__name__ = f'{className}_calc'
globals()[f'{className}_calc'] = Temp
正如 wim 在评论中指出的,您还需要设置 __qualname__
。 Temp.__qualname__ = f'{className}_calc'
编辑:
由于 class 的方法中的名称查找是在运行时(而非编译时)执行的,因此代码片段存在一个错误。 className
将始终引用 classList
中的最后一个元素(在本例中为 baz
),此名称存在于循环范围之外,并将成为 className
的值在所有 classes 的方法中。 (例如:self.column = dataFrame[className]
)。 <--- 这总是 dataFrame['baz']
要解决此问题,必须声明一个名为 className
的 class 级别变量,并将 className
(循环中的变量)分配给它。所以在编译时这个值将被绑定到 class。 class 的方法中对 className
的所有引用都需要更改为 self.className
才能使代码按预期工作。
class Temp:
className = className # note this line
def __init__ (self, dataFrame):
self.column = dataFrame[self.className] # and this line with the original snippet