gpt4 book ai didi

python - 尝试向 Python 类动态添加方法时遇到问题(即 django-tables2 'Table')

转载 作者:太空狗 更新时间:2023-10-30 00:03:31 26 4
gpt4 key购买 nike

因此对于 Django 项目,我真的很希望能够动态生成和显示表(不是基于查询集),而无需事先知道内容或架构。

它看起来像 django-tables2应用程序为呈现表提供了很好的功能,但它要求您通过在自定义 Table 子类上声明属性来显式声明列名,或者为它提供一个模型来推断列。

即,要使用名为“name”的列,您需要:

class NameTable(tables.Table):
name = tables.Column()

Tables 类没有提供事后添加列的方法,因为从阅读源代码来看,它似乎使用了一个元类来清除 __new__ 上的类属性并将它们锁定。

看起来非常简单的元编程将是一个优雅的解决方案。我定义了一个接受列名作为参数的基本类工厂:

def define_table(columns):
class klass(tables.Table): pass
for col in columns:
setattr(klass, col, tables.Column())
return klass

遗憾的是,这不起作用。如果我运行`

x = define_table(["foo", "bar"])(data)
x.foo
x.bar

我回来了:

<django_tables2.columns.base.Column object at 0x7f34755af5d0>
<django_tables2.columns.base.Column object at 0x7f347577f750>

但是如果我列出这些列:

print x.base_columns

我什么也得不到,即 {}

我意识到可能有更简单的解决方案(例如硬着头皮在代码中定义所有可能的数据配置,或者不使用 django-tables2 并自己动手),但我现在将此视为一个机会了解有关元编程的更多信息,所以我真的很想以这种方式完成这项工作。

知道我做错了什么吗?我的理论是 __new__ 方法(​​在 Table 使用的元类中重新定义)是在定义 klass 时调用的,而不是在实例化时调用的,所以当我添加属性时已经太晚了。但这违反了我对何时应该发生 __new__ 的理解。否则,我很难理解元类 __new__ 如何区分代码中定义的属性与动态定义的属性。

谢谢!

最佳答案

您在这里走在正确的轨道上,但是您应该使用 type() 而不是创建准系统类并向其添加属性。内置功能。它没有按照您尝试的方式工作的原因是因为元类已经完成了它的工作。

使用 type() 允许您在设置基类的同时构造一个具有您自己的属性的新类。意思是 - 你可以将你想要的字段描述为你的类的蓝图,允许 Table 的元类在你的定义之后接管。

Here's an exampletype() 与 django 一起使用。我自己在我自己的项目中使用了它(有一些细微的变化),但考虑到您已经快完成了,它应该为您提供了一个不错的起点。

def define_table(columns):
attrs = dict((c, tables.Column()) for c in columns)
klass = type('DynamicTable', (tables.Table,), attrs)
return klass

关于python - 尝试向 Python 类动态添加方法时遇到问题(即 django-tables2 'Table'),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14134488/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com