Python超级方法:类名未定义 [英] Python super method: class name not defined

查看:488
本文介绍了Python超级方法:类名未定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a class defined inside another class like this. Basically I am trying to override the save method in db.Model--it actually just the django.db.models.Model. But when I run this block of code, I see the an 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吗?

According to my understanding, when it is inside GameCenterDB, I should be able to use PublisherTab directly right?

NameError: global name 'PublisherTab' is not defined

像这样的

更改save方法将解决该错误.但是我只是不明白为什么.

Change save method like this will solve the error. But I just do not understand why.

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可以毫无问题地使用?

Also, seems that class PublisherTab(GameCenterDBConfig, db.Model): is interpreted without any error and the mixin worked. Why GameCenterDBConfig can be used without any problem?

推荐答案

据我了解,当它位于GameCenterDB中时,我应该能够直接使用PublisherTab吗?"

"According to my understanding, when it is inside GameCenterDB, I should be able to use PublisherTab directly right?"

错了. Python要求使用类或变量(通常为"self")前缀的类成员具有完全资格.对于在类中声明的任何成员变量,都是如此.例如:

Wrong. Python requires full qualification of class members with either the class or variable (typically 'self') prefix. This is true of any member variable declared within a class. E.g.:

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".

I've added the code at [A]. The program now prints "2" not "1".

为什么不需要在[A]处限制Bar.quux,但是在f()内进行?

Why don't you need to qualify Bar.quux at [A] but you do inside f()?

因为运行[A],该脚本在Foo类的范围之内.

Because when [A] is run, the script is inside the scope of class Foo.

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

But when foo.f() is run, the script is inside the scope of the module because that is where you are calling it from. That's why you need to explicitly declare self in the method definition, and foo.f() is syntactic sugar for Foo.f(foo).

这是Python不那么令人愉快的部分之一.这是很难理解的.

This is one of the less pleasing parts of Python. It makes sense is hard to understand.

这篇关于Python超级方法:类名未定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆