28

python-twitter既存の Python モジュールを拡張するためのベスト プラクティスは何ですか。この場合、基本 API クラスに新しいメソッドを追加してパッケージを拡張したいと考えています。

私は を見てきましたがtweepy、それも気に入っています。python-twitter必要な機能を理解し、拡張するのが簡単だと思います。

私はすでにメソッドを書いています -python-twitterこのモジュールのコアを変更せずに、それらをパッケージモジュールに追加する最もPythonicで混乱の少ない方法を見つけようとしています.

4

6 に答える 6

30

いくつかの方法。

簡単な方法:

モジュールを拡張しないで、クラスを拡張してください。

exttwitter.py

import twitter

class Api(twitter.Api):
    pass 
    # override/add any functions here.

Downside : Every class in twitter must be in exttwitter.py, even if it's just a stub (as above)

A harder (possibly un-pythonic) way:

Import * from python-twitter into a module that you then extend.

For instance :

basemodule.py

 class Ball():
    def __init__(self,a):
        self.a=a
    def __repr__(self):
        return "Ball(%s)" % self.a

def makeBall(a):
    return Ball(a)

def override():
    print "OVERRIDE ONE"

def dontoverride():
    print "THIS WILL BE PRESERVED"

extmodule.py

from basemodule import *
import basemodule

def makeBalls(a,b):
    foo = makeBall(a)
    bar = makeBall(b)
    print foo,bar

def override():
    print "OVERRIDE TWO"

def dontoverride():
    basemodule.dontoverride()
    print "THIS WAS PRESERVED"

runscript.py

import extmodule

#code is in extended module
print extmodule.makeBalls(1,2)
#returns Ball(1) Ball(2)

#code is in base module
print extmodule.makeBall(1)
#returns Ball(1)

#function from extended module overwrites base module
extmodule.override()
#returns OVERRIDE TWO

#function from extended module calls base module first
extmodule.dontoverride()
#returns THIS WILL BE PRESERVED\nTHIS WAS PRESERVED

I'm not sure if the double import in extmodule.py is pythonic - you could remove it, but then you don't handle the usecase of wanting to extend a function that was in the namespace of basemodule.

As far as extended classes, just create a new API(basemodule.API) class to extend the Twitter API module.

于 2010-04-24T20:33:41.000 に答える
6

それらをモジュールに追加しないでください。拡張したいクラスをサブクラス化し、元のものをまったく変更せずに、独自のモジュールでサブクラスを使用します。

于 2010-04-24T20:16:32.010 に答える
6

実行時にモジュール リストを直接操作する方法は次のとおりです。ネタバレ注意: module からモジュール タイプを取得しtypesます。

from __future__ import print_function
import sys
import types
import typing as tx

def modulize(namespace: tx.Dict[str, tx.Any],
             modulename: str,
             moduledocs: tx.Optional[str] = None) -> types.ModuleType:

    """ Convert a dictionary mapping into a legit Python module """

    # Create a new module with a trivially namespaced name:
    namespacedname: str = f'__dynamic_modules__.{modulename}'
    module = types.ModuleType(namespacedname, moduledocs)
    module.__dict__.update(namespace)

    # Inspect the new module:
    name: str = module.__name__
    doc: tx.Optional[str] = module.__doc__
    contents: str = ", ".join(sorted(module.__dict__.keys()))
    print(f"Module name:      {name}")
    print(f"Module contents:  {contents}")
    if doc:
        print(f"Module docstring: {doc}")

    # Add to sys.modules, as per import machinery:
    sys.modules.update({ modulename : module })

    # Return the new module instance:
    return module

…そのような関数を次のように使用できます。

ns = {
         'func' : lambda: print("Yo Dogg"), # these can also be normal non-lambda funcs
    'otherfunc' : lambda string=None: print(string or 'no dogg.'),
      '__all__' : ('func', 'otherfunc'),
      '__dir__' : lambda: ['func', 'otherfunc'] # usually this’d reference __all__
}

modulize(ns, 'wat', "WHAT THE HELL PEOPLE")
import wat

# Call module functions:
wat.func()
wat.otherfunc("Oh, Dogg!")

# Inspect module:
contents = ", ".join(sorted(wat.__dict__.keys()))
print(f"Imported module name:      {wat.__name__}")
print(f"Imported module contents:  {contents}")
print(f"Imported module docstring: {wat.__doc__}")

…もちろん、types.ModuleType新しく宣言された の祖先として指定することにより、独自のモジュール サブクラスを作成することもできます。class私は個人的にこれを行う必要があるとは思っていません。

(また、モジュールからモジュール タイプを取得する必要はありませ。インポート後にtypesいつでも好きなように実行できます。他の多くのビルトインとは異なり、このタイプの 1 つのソースは自明ではないため、具体的に指摘しました。型、Python はグローバル名前空間のモジュール型へのアクセスを提供しません。)ModuleType = type(os)os

実際のアクションはsys.modulesdict にあります。(適切に勇敢な人であれば) 新しいモジュールを追加するだけでなく、既存のモジュールを置き換えることもできます。

于 2018-09-05T11:20:08.370 に答える
3

次のように使用するという古いモジュールがあるとmodします。

import mod

obj = mod.Object()
obj.method()
mod.function()
# and so on...

そして、ユーザーのために置き換えずに拡張したいと考えています。簡単にできます。新しいモジュールに別の名前を付けるnewmod.pyか、より深いパスに同じ名前で配置して、同じ名前のままにすることができます/path/to/mod.py。その後、ユーザーは次のいずれかの方法でそれをインポートできます。

import newmod as mod       # e.g. import unittest2 as unittest idiom from Python 2.6

また

from path.to import mod    # useful in a large code-base

モジュールでは、すべての古い名前を利用できるようにする必要があります。

from mod import *

または、インポートするすべての名前を明示的に指定します。

from mod import Object, function, name2, name3, name4, name5, name6, name7, name8, name9, name10, name11, name12, name13, name14, name15, name16, name17, name18, name19, name20, name21, name22, name23, name24, name25, name26, name27, name28, name29, name30, name31, name32, name33, name34, name35, name36, name37, name38, name39

このユースケースでは、の方が保守しやすいと思います。import *ベース モジュールが機能を拡張すると、シームレスに追いつくことができます (ただし、同じ名前の新しいオブジェクトをシェーディングする可能性があります)。

mod拡張している にまともな がある場合、__all__インポートされる名前が制限されます。

また、 を宣言__all__し、拡張モジュールの で拡張する必要があります__all__

import mod
__all__ = ['NewObject', 'newfunction']
__all__ += mod.__all__   
# if it doesn't have an __all__, maybe it's not good enough to extend
# but it could be relying on the convention of import * not importing
# names prefixed with underscores, (_like _this)

次に、通常どおりにオブジェクトと機能を拡張します。

class NewObject(object):
    def newmethod(self):
        """this method extends Object"""

def newfunction():
    """this function builds on mod's functionality"""

新しいオブジェクトが、置き換える予定の機能を提供する場合 (または、新しい機能を古いコード ベースにバックポートしている場合)、名前を上書きできます。

于 2015-10-26T17:55:43.297 に答える
2

ここでホイールを再発明しないよう提案してもよろしいですか? 6,000 行以上の Twitter クライアントを 2 か月間構築しています。最初は python-twitter もチェックしましたが、最近の API の変更に大きく遅れをとっており、開発もそれほど活発ではないようです。 (少なくとも最後にチェックしたときは)OAuth / xAuthのサポートはありません)。

それで、もう少し検索した後、tweepyを発見しました:
http://github.com/joshthecoder/tweepy

長所: アクティブな開発、OAauth/xAuth、および API の最新情報。
必要なものがすでにそこにある可能性が高いです。

だから私はそれで行くことをお勧めします、それは私のために働いています、私が追加しなければならなかったのはxAuthだけでした(tweepyにマージされました:)

ああ、恥知らずなプラグインです。ツイートを解析したり、HTML にフォーマットしたりする必要がある場合は、私の python バージョンの twitter-text-* ライブラリを使用してください:
http://github.com/BonsaiDen/twitter-text-python

これは unittestetd であり、Twitter.com と同じようにツイートを解析することが保証されています。

于 2010-04-24T21:08:48.860 に答える