我在另一个类中定义了一个类。基本上我试图覆盖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
可以毫无问题地使用?
答案 0 :(得分:2)
“根据我的理解,当它在GameCenterDB中时,我应该可以直接使用PublisherTab吗?”
错误。 Python要求使用类或变量(通常为“self”)前缀对类成员进行完全限定。对于在类中声明的任何成员变量都是如此。 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”。
为什么你不需要在[A]中对Bar.quux进行限定,但是你在f()中做了什么?
因为运行[A]时,脚本位于类Foo的范围内。
但是当运行foo.f()
时,脚本位于模块的范围内,因为这是您从中调用它的位置。这就是为什么你需要在方法定义中明确声明self
,而foo.f()
是Foo.f(foo)
的语法糖。
这是Python不太令人满意的部分之一。这很有道理很难理解。
答案 1 :(得分:0)
你想这样做:
class GameCenterDB(object):
class GameCenterDBConfig(object):
class Config(object):
pass
class PublisherTab(GameCenterDB.GameCenterDBConfig, db.Model):
pass
class Meta:
pass
def save(self, *args, **kwargs):
super(GameCenterDB.PublisherTab, self).save(*args, **kwargs)
您需要从全局范围引用这些类名。