super() 的第一个参数必须是类型,而不是 None

1 投票
2 回答
6048 浏览
提问于 2025-04-16 20:14

我在我的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 命令。)

https://github.com/benoitc/gunicorn/issues/222

撰写回答