Python super 方法: class name not defined

标签 python django namespaces

我在另一个类中定义了一个类,如下所示。基本上我试图覆盖 save db.Model 中的方法——它实际上只是 django.db.models.Model 。但是当我运行这段代码时,我看到 NameError .

class GameCenterDB:
    class GameCenterDBConfig:
        class Config:
            db_for_read = "game_center_db.slave"
            db_for_write = "default"

    class PublisherTab(GameCenterDBConfig, db.Model):
        publisher_id = db.PositiveIntegerField(primary_key=True)
        name = db.CharField(max_length=100)
        create_time = db.PositiveIntegerField()
        update_time = db.PositiveIntegerField()

        class Meta:
            db_table = u'publisher_tab'

        def save(self, *args, **kwargs):
            curr_time = int(time.time())
            if not self.create_time:
                self.create_time = curr_time
            self.update_time = curr_time
            # See the line below, this triggers an error
            # NameError: global name 'PublisherTab' is not defined
            super(PublisherTab, self).save(*args, **kwargs)

根据我的理解,当它在GameCenterDB内部时,我应该可以直接使用PublisherTab吧?

NameError: global name 'PublisherTab' is not defined

更改save这样的方法就可以解决这个错误。但我就是不明白为什么。

def save(self, *args, **kwargs):
     curr_time = int(time.time())
     if not self.create_time:
         self.create_time = curr_time
     self.update_time = curr_time
     super(GameCenterDB.PublisherTab, self).save(*args, **kwargs)

另外,似乎 class PublisherTab(GameCenterDBConfig, db.Model):被解释没有任何错误并且 mixin 起作用了。为什么GameCenterDBConfig可以正常使用吗?

最佳答案

“根据我的理解,当它在GameCenterDB内部时,我应该可以直接使用PublisherTab吧?”

错了。 Python 要求使用类或变量(通常为“self”)前缀对类成员进行完全限定。对于类中声明的任何成员变量都是如此。例如:

class Foo:
    class Bar:
        quux = 1
    def f(self):
        print "Foo.Bar.quux: %d" % Foo.Bar.quux
        print "self.Bar.quux: %d" % self.Bar.quux
foo = Foo()
foo.f()

现在考虑这个例子:

# scope is top-level module
class Foo:
   # scope is Foo
    class Bar:
        # scope is Foo.Bar
        quux = 1
    # scope is Foo
    Bar.quux = 2 # [A]
    try:
        print "x: %d" % x
    except NameError:
        print "x gave an error because it is outside scope"
    def f(self):
        # scope is Foo when we are defining but not when we are running!
        try:
            print "Bar.quux: %d" % Bar.quux
        except NameError:
            print "Bar.quux gave us an error because it is outside scope"
        print "Foo.Bar.quux: %d" % Foo.Bar.quux
        print "self.Bar.quux: %d" % self.Bar.quux
        print "x is in scope: %d" % x
# scope is top-level module again
x = 456
foo = Foo()
foo.f()

我已在 [A] 添加代码。程序现在打印“2”而不是“1”。

为什么不需要在 [A] 处限定 Bar.quux 但需要在 f() 内限定?

因为当[A]运行时,脚本位于类Foo的范围内。

但是当foo.f()运行时,脚本位于模块的范围内,因为这是您调用它的地方。这就是为什么你需要在方法定义中显式声明 self,而 foo.f()Foo.f(foo) 的语法糖.

这是 Python 中不太令人愉快的部分之一。说得有理却很难理解。

关于Python super 方法: class name not defined,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35149265/

相关文章:

python - 如何在 Azure 数据工厂中集成 Python 代码

python - 无法在我的 debian GCE 实例上安装 Apns

python - 如何在不评估的情况下拆分 Django 查询集?

c# - 有没有办法在 VB 中转义根命名空间?

python - 在 Ubuntu 9.10 的 Gnome 上安装 TortoiseHG?

python - 查找字符串中某个单词之后的下一个单词

php 脚本无法读取带有冒号的 xml 数据 (:)

Python 命名空间 : How to make unique objects accessible in other modules?

python - 在 PyCharm 中运行测试如何导致 "Model class doesn' t declare an explicit app_label"错误?

python - Django 模型,与反向引用的一对多关系 [如何]