我有一个脚本,其中必须定义几个类:
class track1:
number = 0
min_class = 0
members = []
class track2:
number = 0
min_class = 0
members = []
class track3:
number = 0
min_class = 0
members = []
依此类推...
稍后,我在某些类中更改了值。例如:在类2,5和6中,min_class将为10。或者成员列表在每个不同的轨道中将包含不同的成员。
但是有时候我必须定义四个类,有时候是16个。
所以我的问题是:有没有办法在Python循环中定义类?
for i in range(x):
#define class track i
答案 0 :(得分:1)
是-可以做到。唯一奇怪的部分是强制动态创建的类实际上在模块中具有名称-尽管可以通过写到globals()
字典来完成。
无论如何,在Python中动态创建类的是对type
的调用:该类是实例。
因此,如果类具有相同的主体,那么一种简单的方法是为所有类创建一个基类,然后可以在模块级别进行操作:
class Base:
attributes = 0
...
for i in range(16):
globals()[f'class{i}'] = type(f'class{i}', (Base,), {})
根据名称的读取方式,如果名称是唯一的问题,则可以编写一个for循环,并在其中声明类,只需注意名称-创建一个类使用class
kewyord块和使用type
是等效的(但是对于静态分析工具,例如IDE使用的自动完成器,无论如何,这些东西都会丢失)
for i in range(16):
class Base:
attributes = []
...
Base.__name__ = f"class{i}"
globals()[f"class{i}"] = Base
但是,正如我在开始时所述,在Python代码中动态创建变量并不常见-在这里,变量是指带有静态名称的任何内容,包括函数和类-如果您输入的是硬编码名称这样的类在另一个“ .py”文件中,应在此处进行硬编码。 因此,如果要动态使用您的类,可以说其他一些代码必须根据其他数据来选择这些类中的特定类,那么将它们绑定为“ class1,class2”等模块并不方便。 。相反,它们应该是另一个数据结构的一部分,例如列表或字典-假设您希望一个这样的类取决于代码的其他部分具有的“产品类别”-您也可以创建一个字典其键是产品类别,值是类别。 或者,为简单起见,我们只列出一个列表:
myclasses = []
for i in range(16):
myclasses.append(type(f"class{i}", (Base,), {})
(带有类主体的表单也是有效的,唯一的区别是您没有将生成的类分配给globals()
中的字典,而是分配给了另一个数据结构。
答案 1 :(得分:1)
使用type
函数动态创建类。
track = []
for i in range(x):
track.append(type('track%d' % i, (), {'number': 0, 'min_class': 0, 'members': []}))
答案 2 :(得分:0)
您的类定义是相同的。 为什么没有一个类定义:
class track:
number = 0
min_class = 0
members = []
,然后根据需要创建任意数量的实例?
L = []
for i in range(x):
L.append(track())
现在,您可能希望类成员成为实例成员,因此需要适当使用self
。
答案 3 :(得分:0)
您已经多次创建类trackX
,但是您需要创建一个类的实例:
class Track:
number = 0
min_class = 0
members = []
def __init__(number, min_class, members):
self.number = number
self.min_class = min_class
self.members = members
然后在循环中创建类的实例:
for i in range(x):
track = Track(number, min_class, members)
如果您想要曲目列表,只需将此曲目附加到曲目列表即可:
tracks = []
for i in range(x):
track = Track(number, min_class, members)
tracks.append(track)
答案 4 :(得分:0)
设计和编程的很大一部分是避免或消除重复。
这是您要尝试做的,所以这是一个好的开始。
但是,唯一不同的是类的名称,这似乎是一件很奇怪的事情。
实例化类时,对象类型之间基本上没有其他区别。
在设计中,您希望封装保持不变的内容(例如,类或算法),并使用变化的内容(数据)对其进行参数化。
我建议您使用轨道名称来参数化对象构造函数:
class Account(models.Model):
account_id = id_field.PrimaryIDField()
name = models.CharField(max_length=100)
created = models.DateTimeField(_("date joined"), auto_now_add=True, editable=False)
modified = models.DateTimeField(_("date modified"), auto_now=True)