我在另一个类中定义了一个类,如下所示。基本上我试图覆盖 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/