对于继承自Base
类的SQLAlchemy对象,我可以将参数传递给未在构造函数中定义的变量的类:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
name = Column(String(50))
fullname = Column(String(50))
password = Column(String(12))
def __repr__(self):
return "<User(name='%s', fullname='%s', password='%s')>" % (
self.name, self.fullname, self.password)
ed_user = User(name='ed', fullname='Ed Jones', password='edspassword')
当然,如果我试图将这样的参数传递给另一个类,以同样的方式设置类变量,我会得到一个错误:
^{pr2}$SQLalchemy在搞什么鬼把戏?他们为什么不使用构造函数(即__init__
方法)?在
你实际上问了两个问题。在
首先,你问“SQLAlchemy在搞什么鬼把戏”。在幕后还有一些事情要做,使用一个名为Metaclasses的概念来动态创建
Base
类。在但实际上,您只需要知道SQLAlchemy是在动态设置元素的
Base
类中定义一个构造函数(尽管是迂回的)。Here实际上是该方法的实现(至少在回答这个问题时它是存在的):基本上,这是dynamically determining the keyword arguments,并自动设置新对象的属性。您可以将
^{pr2}$Base
类想象为如下所示,但请记住它实际上要复杂一些(您可以阅读代码以了解更多信息):如果您创建了上面的代码,您创建的继承自
Base
的任何类都将自动获得自动填充属性属性的能力,只要该属性已经在该类上定义。这是因为典型的Python面向对象的继承结构:如果不在User
对象上定义方法,Python会查找在基类上定义的方法(在本例中是Base
方法),并将使用它。这适用于__init__
方法,就像任何其他方法一样。在你的第二个问题是“为什么他们不使用一个构造函数(即
__init__
方法)好吧,正如我们上面所描述的,他们是这样的!他们将_declarative_constructor
方法设置为__init__
属性Base
类,有效地设置了对象构造的默认逻辑。当然,这只定义了默认值;如果您想。。。在相关问题 更多 >
编程相关推荐