This question already has an answer here:
Nested class is not defined in itself
                                
                                    (1个答案)
                                
                        
                                3年前关闭。
            
                    
我有一个这样的另一个类中定义的类。基本上,我试图覆盖db.Model中的save方法-实际上它只是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 - python super方法:类名未定义,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35149265/

10-14 15:13
查看更多