【发布时间】:2015-04-10 19:49:04
【问题描述】:
我正在尝试根据一些 Python 类的定义自动创建一些 SQL 表,我尝试使用 dir(),但由于它返回一个 Python 字典,因此它没有排序,因此类成员的定义顺序丢失了。
在网上阅读我发现了以下here
class OrderedClass(type):
@classmethod
def __prepare__(metacls, name, bases, **kwds):
return collections.OrderedDict()
def __new__(cls, name, bases, namespace, **kwds):
result = type.__new__(cls, name, bases, dict(namespace))
result.members = tuple(namespace)
return result
class A(metaclass=OrderedClass):
def one(self): pass
def two(self): pass
def three(self): pass
def four(self): pass
>>> A.members
('__module__', 'one', 'two', 'three', 'four')
我成功地实现了它的一个副本,它似乎正在做它应该做的事情,只是它只将methods 保存在members 变量中,而且我还需要有 class 成员变量。
问题:
如何获得保留其定义顺序的成员变量列表?我不关心类方法,实际上我忽略了它们。
注意:之所以顺序很重要,是因为表会有引用某些表列的约束,而且必须在定义列之后,而它们却出现在之前。
编辑:这是我真实程序中的示例类
class SQLTable(type):
@classmethod
def __prepare__(metacls, name, bases, **kwds):
return OrderedDict()
def __new__(cls, name, bases, namespace, **kwds):
result = type.__new__(cls, name, bases, dict(namespace))
result.members = tuple(namespace)
return result
class AreaFisicoAmbiental(metaclass = SQLTable):
def __init__(self, persona, datos):
# edificacion
self.persona = persona
self.tipoEdificacion = datos[0]
self.tipoDeParedes = datos[1]
self.detallesTipoDeParedes = datos[2]
self.tipoDeTecho = datos[3]
self.detallesTipoDeTecho = datos[4]
self.tipoDePiso = datos[5]
self.detallesTipoDePiso = datos[6]
# ambientes
self.problemaDeInfraestructura = datos[7]
self.detallesProblemaDeInfraestructura = datos[9]
self.condicionDeTenencia = datos[10]
self.detallesCondicionDeTenencia = datos[11]
self.sala = toBool(datos[12])
self.comedor = toBool(datos[13])
self.baño = toBool(datos[14])
self.porche = toBool(datos[15])
self.patio = toBool(datos[16])
self.lavandero = toBool(datos[17])
self.habitaciones = toInt(datos[19])
# servicios básicos
self.aguasServidas = toBool(datos[21])
self.aguaPotable = toBool(datos[22])
self.luz = toBool(datos[23])
self.gas = datos[24]
self.internet = toBool(datos[25])
在做
print(AreaFisicoAmbiental.members)
输出:
('__module__', '__qualname__', '__init__')
变量名称是西班牙语,因为它们的名称将用作表列名称,也用作将从数据库结构生成的 Web 应用程序的标签。
我知道 Django 会做这样的事情,但我已经有我的数据库检查器来做相反的事情,所以知道我需要一个类似 Django 的功能来使用我的生成器。
【问题讨论】:
-
你有没有想过为此使用 Django?或者至少看看它的模型代码是如何工作的?它正是这样做的。
-
class A没有定义任何成员变量。尝试在其定义中添加member_var = 42。无论如何,听起来您真正想要的是实例数据成员的副本。 -
@martineau 我的类确实定义了成员变量,我将发布其中一个。
-
既然这就是您的问题的全部内容,请务必这样做。
-
所有用
self.xxx = whatever定义的项目都是实例属性,在类定义时不存在。
标签: python python-3.x introspection metaclass