3

を使用したいのですpython-twitterが、クラスを拡張しStatusていくつかの新しいメソッドと属性を追加します。これを行うためのpythonicの方法は何ですか?

現時点では、属性と新しい機能をに追加する関数がありますStatus

process_status(status):
    status.datetime = ...
    status.phrase = ...

prettyprint_status(status):
    # do something...

当然、コンストラクターに余分なメソッドを追加したいだけStatusです。次のように、各クラスの新しい実装を含む新しいモジュールを作成することを提案する、これについて議論しているスタックオーバーフローの質問を見つけました。ext-twitter

# ext_twitter.py
import twitter

class Api(twitter.Api):
    pass

class Status(twitter.Status):
    def __init__(self, *args):
        twitter.Status.__init__(self, *args)
        self.args = args
        self.time = parseTime(self.created_at)
        self.phrase = ...

    def prettyprint(self):
        # something

ただし、Statusクラスは Twitter API オブジェクトによって生成され、ここでは拡張された Status クラスへの参照を持たないext-twitter.Api()呼び出しであるため、これは機能しません。python-twitter.Api()

フォークして独自のバージョンを作成せずに、機能を python-twitter モジュールに追加する方法はありますか?

4

2 に答える 2

2

これを試して:

# patch_twitter.py
import twitter

TwitterStatus = twitter.Status

class Status(TwitterStatus):
     def __init__(self, *args, **kwargs):
        TwitterStatus.__init__(self, *args, **kwargs)
        self.args = args
        self.time = parseTime(self.created_at)
        self.phrase = ...

    def prettyprint(self):
        # something

twitter.Status = Status

# use api

これは、少なくとも「仕事」のいくつかの値に対しては機能するはずです。に最初に格納されたクラス オブジェクトへの参照をキャプチャするものが他にある場合twitter.Status、それらの参照は更新されません。これはあまり頻繁には発生しませんが、微妙なバグの原因になる可能性があります。

インポート後すぐに、twitter.py他の操作を行う前に、これをインポートする必要があります。

于 2013-05-11T22:57:29.473 に答える
1

継承を使用する代わりに、コンポジションを使用してStatusオブジェクト に機能を追加できます。

# ext_twitter.py
import twitter

class Api(twitter.Api):
    def method_that_returns_status(self, *args, **kwargs):
        status = super(Api, self).methot_that_returns_status(*args, **kwargs)

        # wrap the original status with your custom status
        return Status(status)


class Status(object):        
    def __init__(self, status):
        self._internal = status

    def __getattr__(self, attr):
        return getattr(self._internal, attr)

    def __setattr__(self, attr, value):
        if attr == '_internal':
            super(Status, self).__setattr__(attr, value)
        else:
            setattr(self._internal, attr, value)

    def prettyprint(self):
        # something
于 2013-05-11T23:01:18.143 に答える