Python类__init__不工作

时间:2013-06-23 00:22:04

标签: python class sqlalchemy

这是我在sqlalchemy中使用的一些非常简单的代码,我在这里遗漏了一些关于类如何工作的基本知识。

class Game(Base):
    __tablename__ = "games"

    id = Column(Integer, primary_key=True)
    a_name = Column(String)

    def __init__(self, **kwargs):
        for k, v in kwargs.iteritems():
             setattr(self, k, v)
        print 'hi'
        self.away_dictionary =  {'name': self.a_name}

    @hybrid_property
    def stuff(self):
        return self.away_dictionary

以下查询有效:

session.query(Game).first().a_name

但以下查询返回错误:

session.query(Game).first().stuff
'Game' object has no attribute 'away_dictionary'

我还有一个更基本的问题,当我查询Game类时,它不会打印出'hi'。那么有人可以解释为什么每次我使用游戏实例时都不会打印出“hi”吗?第二个问题是我如何构建和访问我想要为这个类的每个实例拥有的away_dictionary?

4 个答案:

答案 0 :(得分:1)

啊哈哈。我刚要指出,stuff找不到away_dictionary是奇怪的,我希望找不到away_dictionary ...而且您编辑了帖子并更改了错误消息你在引用。确实__init__()确实无法找到它,因为它通常是在您班级的__init__()方法中创建的,并且__init__()没有被调用。

通常,在创建实例时会调用__init__(),但是当您在SQLAlchemy的查询中使用该类时,它会跳过declarative_mapper方法。我怀疑这与SQLAlchemy的__init__()如何工作有关,但我在SQLAlchemy上已经足够生疏,我不知道如何修复它。如果我发现,我会稍后编辑这个答案然后告诉你。

但是现在,您可能不应该依赖于在您的SQLAlchemy模型对象中调用的Base方法(即,从{{1}}派生的任何东西)。看看你是否可以用其他方式构建代码。

答案 1 :(得分:1)

感谢您的评论。它只是我还是sqlalchemy有点令人困惑?

无论如何,正如人们在上面指出的那样__init__方法在你进行查询时显然没有被调用。

  

在重新创建对象时,SQLAlchemy ORM不会调用__init__   数据库行。 ORM的过程有点类似于Python   标准库的pickle模块,调用低级__new__   方法,然后直接在实例上静默恢复属性   而不是致电__init__

解决方法是添加以下代码:

from sqlalchemy.orm import reconstructor
@reconstructor
awesome_true_init(self):
    self.away_dictionary = {'hi': 'i work!!'}

这个函数就像一个真实的__init__,每当你创建对象时都会被调用!!

答案 2 :(得分:0)

您没有在上面的查询中创建游戏实例,只传递Game类对象。因此永远不会调用 init ()构造函数。 如果您需要Game实例进行查询,则需要:session.query(Game()).first().stuff

答案 3 :(得分:-2)

session.query(Game).first().a_name的作用原因,但session.query(Game).first().stuff不是一个简单的语法问题。 a_name是一个变量,是Game类的一个属性,因此只需键入a_name即可引用它。另一方面,东西是该类的一种方法,因此你需要一对括号,即使在这种情况下,它们内部也没有任何东西。所以尝试使用session.query(Game).first().stuff()

“hi”未打印,因为只有在使用该构造函数创建对象时才会调用 init ,而该查询未执行此操作。