我编写了一个小函数,用于在 Python 中利用槽动态地制定类(或者更具体地说,类似 C 的结构,嗯,或多或少)。我想知道我是否做对了一切。这些类可以实例化,但我怀疑插槽没有被正确使用。相反,我不知道它们是否确实被正确使用。
def formulate(name, **data):
def __init__(self, **data):
self.__dict__.update(data)
struct = type(name, (), data)
struct.__init__ = __init__
struct.__slots__ = data.keys()
return struct
谢谢。 艾丽莎。
最佳答案
包含 __slots__
和 __init__
作为字典中的键
传递给类型
:
def formulate(name, **data):
def __init__(self): # 1
for key, val in data.items():
setattr(self, key, val) # 2
struct = type(name, (), {'__slots__': tuple(data.keys()), '__init__': __init__})
return struct
Bar = formulate('Bar', **dict(a=1, b=2)) # 3
bar = Bar() # 4
print('__dict__' in dir(bar))
# False
print('__slots__' in dir(bar))
# True
print(bar.__slots__)
# ['a', 'b']
print(bar.a)
# 1
请注意,我更改了
__init__
的定义def __init__(self, **data):
到
def __init__(self):
如果您使用原始版本,则用于更新的
数据
槽键必须通过调用Bar
提供:bar = Bar(**dict(a=1, b=2))
这会很糟糕,因为它需要你重复相同的字典 两次——一次在#4,一次在#3。
您似乎更有可能希望#3 控制初始值 插槽键。在这种情况下,请勿将
data
列为__init__
。通过省略它,Python 使用 LEGB rule看看 增加data
的值。它会在封闭的范围内找到它formulate
函数。__init__
则被称为 a closure .由于具有
__slots__
的类没有__dict__
属性 默认情况下,我们不能/不应该使用 self.__dict__.update(data) 。 相反,请使用setattr
设置插槽键。
关于class - 在 Python 中制定动态类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22377735/