python中调用类未定义,Python超级方法:类名未定义

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)

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

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)

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?

解决方案

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

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()

Now consider this example:

# 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()

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

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

Because when [A] is run, the script is inside the scope of class 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).

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值