1

今日の午後、へのカスタム拡張機能のバグを見つけるために数時間を費やしましたurllib2.Request。問題は、私が知ったように、super(ExtendedRequest, self)urllib2.Request私はPython 2.5を使用しています)まだ古いスタイルのクラスであり、使用super()できないため、の使用法でした。

両方の機能を備えた新しいクラスを作成する最も明白な方法は、

class ExtendedRequest(object, urllib2.Request):
    def __init__():
        super(ExtendedRequest, self).__init__(...)

動作しません。それを呼んで、私はAttributeError: typeによって育てられたままになっていurllib2.Request.__getattr__()ます。さて、開始してコピーする前に、urllib2.Requestクラス全体を/ usr / lib / pythonから貼り付けて、次のように書き直します。

class Request(object):

誰かがアイデアを持っています、どうすればこれをよりエレガントな方法で達成できますか?(これ、の作業サポートに基づいた新しいスタイルのクラスを持つことです。)urllib2.Requestsuper()

編集:ちなみに:言及されたAttributeError:

>>> class ExtendedRequest(object, urllib2.Request):
...   def __init__(self):
...     super(ExtendedRequest, self).__init__('http://stackoverflow.com')
...
>>> ABC = ExtendedRequest ()
>>> d = urllib2.urlopen(ABC)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/urllib2.py", line 124, in urlopen
    return _opener.open(url, data)
  File "/usr/lib/python2.5/urllib2.py", line 373, in open
    protocol = req.get_type()
  File "/usr/lib/python2.5/urllib2.py", line 241, in get_type
    if self.type is None:
  File "/usr/lib/python2.5/urllib2.py", line 218, in __getattr__
    raise AttributeError, attr
AttributeError: type
4

3 に答える 3

1

階層が単純なので、これは正常に機能するはずです

class ExtendedRequest(urllib2.Request):
    def __init__(self,...):
        urllib2.Request.__init__(self,...)
于 2010-02-15T15:46:41.647 に答える
1

スーパーを使用することが常にベストプラクティスであるとは限りません。スーパーを使用することには多くの困難があります。例については、JamesKnightのhttp://fuhm.org/super-harmful/をお読みください。

そのリンクは(他の問題の中でも)次のことを示しています

  1. スーパークラスは、サブクラスが使用する場合はスーパーを使用する必要があります
  2. superを使用するすべてのサブクラスの__init__シグニチャは一致する必要があります。受け取ったすべての引数をスーパー関数に渡す必要があります。階層内__init__の他のクラスの__init__メソッドを呼び出す準備をする必要があります。
  3. で位置引数を使用しないでください__init__

あなたの状況では、上記の各基準に違反しています。

ジェームズナイトも言います、

super()が実際に役立つ唯一の状況は、ダイヤモンドの継承がある場合です。それでも、思ったほど役に立たないことがよくあります。

スーパーが正しく使える条件はかなり面倒なので、スーパーの有用性はかなり限られていると思います。サブクラス化よりもコンポジションデザインパターンを優先します。可能であれば、ダイヤモンドの継承は避けてください。オブジェクト階層を上(オブジェクト)から下まで制御し、非常に一貫して使用する場合は、問題ありません。ただし、この場合、クラス階層全体を制御するわけではないため、を使用しないことをお勧めしますsuper

于 2010-02-15T20:46:37.823 に答える
0

サンプルのinitの定義にselfパラメーターを渡すことができなかったと思います。これを試してください:

class ExtendedRequest(object, urllib2.Request):
    def __init__(self):
        super(ExtendedRequest, self).__init__(self)

私はそれをテストしました、そしてそれは大丈夫に働くようです:

>>> x = ExtendedRequest()
>>> super(ExtendedRequest, x)
<super: <class 'ExtendedRequest'>, <ExtendedRequest object>>
于 2010-02-15T15:50:07.690 に答える