python - 你可以在 python 中循环创建类吗?
问题描述
我有一种情况,我正在制作一堆类,其中一堆实际上基本相同,所以我想让它们循环起来。它们与注册系统一起使用,因此在使用方面没有问题,但我不确定如何实际定义一个具有确定类名的变量的类......
简单的例子:
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 DB 一起使用的,而且要复杂得多……我只是不想捍卫“你为什么要这样做?” 我有充分的理由,就这样吧。
classname 在 class 行的 {{{ }}} 中,表示它是一个变量,实际上在语法上并不正确。问题是“我如何表示我使用 {{{ }}} 的目的?” 我认为。
答案可能是元类,但我仍然不确定如何使我的类变量的名称....
ETA:尝试使用@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'
这只是给我 baaz 课。这三个都在给baaz...我在做一些很愚蠢的事情吗?
解决方案
你可以这样做,使用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
如果你想改变你的班级名称,那么你可以这样做
Temp.__name__ = f'{className}_calc'
globals()[f'{className}_calc'] = Temp
正如 wim 在评论中指出的那样,您还需要设置__qualname__
.Temp.__qualname__ = f'{className}_calc'
编辑:
由于类方法中的名称查找是在运行时(而不是在编译时)执行的,因此代码片段有一个错误。className
将始终引用classList
(baz
在这种情况下) 中的最后一个元素,此名称存在于循环范围之外,并且将是className
所有类的方法中的值。(例如:)self.column = dataFrame[className]
。<--- 这总是dataFrame['baz']
要解决此问题,必须声明一个名为的类级别变量className
并将className
(来自循环的变量)分配给该变量。所以在编译时这个值将绑定到类。所有对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
推荐阅读
- jsp - thymeleaf 无法解析表达式
- css - 如何使 css hover/focus 伪类正常工作
- python - 尝试使用 Django 框架在 html 表中呈现数据库中的数据
- cypress - 使用 cypress 存根网络请求
- reactjs - 警告:无效的 DOM 属性 `tabindex`。您是说“tabIndex”吗?
- node.js - 无法在 Azure 上发出 POST 请求 - EACCES
- python-3.x - `fixed-point` 中的内部 `try` 交互
- java - 如何在数组列表(Java)中搜索对象的元素,如果存在,则打印该对象的 .toString
- swift - 子类和超类的 Swift 约束协议
- java - 从子类对象调用非覆盖方法