我需要来自数据库的类运行时类声明。
某些类需要覆盖字段和重新声明。
models.py
class Staff(object): name = StringField( verbose_name = "Full name") age = IntegerField( verbose_name = "Age")
utils.py
def class_changer(class_path, field_key, new_Field): pass ??????
>>> class_changer("models.Staff", "gender", BooleanField()) # Add new field to Staff
>>> class_changer("models.Country", "name", StringField()) # Add new class with name field
>>> class_changer("models.Staff", "country", ForeignKey("Country")) # Add new field to Staff
结果是
class Staff(object): name = StringField( verbose_name = "Full name") age = IntegerField( verbose_name = "Age") gender = BooleanField() country = ForeignKey("Country") class Country(object): name = StringField()
如何实现class_changer?
答案 0 :(得分:4)
你需要更好的架构,但作为一个起始的解决方案你可以试试这个,
In [12]: class a1(object):
...: pass
In [13]: def class_changer(cls_path, attr, val):
....: try:
....: obj = eval(cls_path)
....: setattr(obj, attr, val)
....: except:
....: raise
....:
In [14]: def getGender(self):
...: return True
In [15]: class_changer('a1','getGender', getGender)
In [16]: a1().getGender()
Out[16]: True
答案 1 :(得分:1)
首先向类中添加新属性:
>>> class_changer("models.Staff", "gender", BooleanField()) # Add new field to Staff
>>> class_changer("models.Staff", "country", ForeignKey("Country")) # Add new field to Staff
对于这两个,请直接设置Staff
:
models.Staff.gender = BooleanField()
models.Staff.country = ForeignKey("Country")
或者说它是通用的:
def add_to_class(cls, name, attr):
setattr(cls, name, attr)
add_to_class(models.Staff, "gender", BooleanField())
add_to_class(models.Staff, "country", ForeignKey("Country"))
其次,创建一个新类:
>>> class_changer("models.Country", "name", StringField()) # Add new class with name field
您可以在函数中创建一个类,然后将其分配给模块:
def new_class(mod, name):
class New(object): pass
setattr(mod, name, New)
new_class(test, "Country")
add_to_class(test, "Country", StringField())
我不确定你想要合并new_class
和add_to_class
,但我想你可以这样做:
def create_if_needed_and_add_to_class(mod, clsname, attrname, value):
if clsname not in dir(mod):
new_class(mod, clsname)
add_to_class(mod, attrname, value)
然后最后为您的class_changer
:
def class_changer(mod_clsname_string, attrname, value):
modname, clsname = '.'.split(mod_clsname_string)
create_if_needed_and_add_to_class(globals()[modname], clsname, attrname, value)
编辑:修复class_changer
以使用locals()
进行模块名称查找,因为它是字符串而不是模块。
编辑:oops,它应该是globals()
。