super() 的第一个参数必须是类型,而不是 None
我在我的Django应用程序的一个模块里,有一个类在构造的时候遇到了问题,使用了super...
class LinkshareExternalAffiliateProperties(AffiliateExternalProperties):
def __init__(self, aggregator_affiliate_id, account_username, account_password, api_token):
super(LinkshareExternalAffiliateProperties, self).__init__(aggregator_affiliate_id)
self.account_username = account_username
self.account_password = account_password
self.api_token = api_token
class AffiliateExternalProperties(object):
def __getattribute__(self, attr):
sources = super(AffiliateExternalProperties, self).__getattribute__('__sources__')
if attr in sources:
return self.get(attr)
else:
return super(AffiliateExternalProperties, self).__getattribute__(attr)
当我调用这段代码时,出现了一个错误:super()的第一个参数必须是类型,而不能是None。为什么LinkshareExternalAffiliateProperties在这里会变成None呢?它应该是这个新实例的类啊!而且同一个模块里的其他类在这个时候也无法使用。
一些有趣的事情(这个问题有点复杂,但其中某些部分可能是导致问题的原因...):
class Aggregator(models.Model):
foo = columns
@property
def proxy(self):
if self.name == 'Linkshare':
return Linkshare.objects.get_instance()
elif self.name == 'Commission Junction':
return CommissionJunction.objects.get_instance()
elif self.name == 'Share-A-Sale':
return ShareASale.objects.get_instance()
else:
raise Exception('Invalid aggregator name "%s". Excpected Linkshare, Commission Junction, or Share-A-Sale.' % self.name)
class Linkshare(models.Model):
def affiliate_properties(self, aggregator_affiliate_id):
return LinkshareExternalAffiliateProperties(aggregator_affiliate_id, self.username, self.password)
class Affiliate(models.Model):
foo = columns
def get_external_properties():
return self.aggregator.proxy.get_external_properties(self.aggregator_affiliate_id)
class MyView(self):
def view(self, request):
affiliate = get_object_or_404(Affiliate, pk=id)
properties = affiliate.get_external_properties()
return render_to_response('admin/affiliates/affiliate/affiliate_scrape_ajax.html', dict(scrape=properties))
在浏览器中访问/view时会出现这个错误...
有趣的是,在本地运行这段代码时,一切正常,没有错误。
但是当我用gunicorn和nginx运行时,就出问题了。
2 个回答
1
确保你在声明类之后没有重新给它赋值。下面的代码会导致你看到的错误:
class foo(object):
def x(self):
print "foo"
class bar(foo):
def x(self):
super(bar, self).x()
baz = bar
bar = None
a = baz()
a.x()
0
Gunicorn 有个 bug:
在 Django 中使用 run_gunicorn
加上重载功能时,
解决重载问题的一种方法是用 Django 的
un_gunicorn
命令配合 manage.py,考虑到重载其实就是重新执行。所以我们要确保所有模块都被重新加载。但是这样做的话,进程的 ID 会改变,有些监控工具可能无法检测到这个变化,特别是如果它们没有使用 pidfile 的话。(换句话说,我们强烈建议大家如果想要支持 HUP 功能的话,使用gunicorn_django
命令。)