2010-04-24 10 views
14

Was sind die besten Praktiken für die Erweiterung eines Python-Moduls - in diesem Fall möchte ich python-twitter erweitern, indem ich neue Methoden zur Basis-API-Klasse hinzufüge.Wie erweitere ich ein Python-Modul? (python-twitter)

Ich habe auf Tweepy geschaut, und ich mag das auch, ich finde Python-Twitter einfach zu verstehen und zu erweitern mit der Funktionalität, die ich will.

Ich habe die Methoden bereits geschrieben, ich versuche nur herauszufinden, die beste Möglichkeit, sie in das Modul hinzuzufügen, ohne den Kern zu ändern.

+0

Sie haben sich zu fragen, was es Sie sind Der Versuch, dies zu erreichen, kann für Sie nicht gelöst werden, indem Sie die Funktionalität vom vorhandenen Modul ableiten. – jathanism

+0

Interessanter Thread in der Python-News-Gruppe zu dem, was ich ursprünglich gesucht habe, führte mich zu diesem Q & A, Thread ist wie, vor 13 Jahren: https://mail.python.org/pipermail/python-dev/2002-June /024839.html –

Antwort

17

Ein paar Möglichkeiten.

Der einfache Weg:

Sie das Modul nicht erweitern, die Klassen erweitern.

exttwitter.py

import twitter 

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

Nachteil: Jede Klasse in twitter in exttwitter.py sein muss, auch wenn es (wie oben) nur ein Stummel ist

Ein härteres (möglicherweise un-pythonic) weg:

Importieren * von python-twitter in ein Modul, das Sie dann erweitern.

Zum Beispiel:

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 

Ich bin mir nicht sicher, ob der Doppel Import in extmodule.py ist Python ic - Sie könnten es entfernen, aber dann behandeln Sie nicht den Anwendungsfall, eine Funktion zu erweitern, die sich im Namensraum von basemodule befand.

Für erweiterte Klassen erstellen Sie einfach eine neue API (basemodule.API) -Klasse, um das Twitter-API-Modul zu erweitern.

+0

danke, ich suchte nach etwas, um json.dumps über mein ganzes Projekt zu überschreiben. (während ich die anderen Funktionen behalte) – njzk2

+0

Ich würde das nicht für unpythonisch halten. Es sind nützliche Tricks wie diese, die Python so mächtig machen können. Sei nur offensichtlich, was du tust. Versuchen Sie das in Java oder C++ :-) – ThatAintWorking

6

Fügen Sie sie nicht dem Modul hinzu. Unterklassen Sie die Klassen, die Sie erweitern möchten, und verwenden Sie Ihre Unterklassen in Ihrem eigenen Modul, ohne den ursprünglichen Inhalt zu verändern.

+0

Ok, ich bin noch nicht vertraut mit Sub-Classing in Python, (ich bin ein Ingenieur, immer noch daran gewöhnt, OO-Stil), haben Sie eine Lieblings-Ressourcen? Also, im Grunde gibt es nichts Besonderes an einem Modul ... Ich kann nur ein neues Modul schreiben, das Python-twitter API-Klasse als Basisklasse verwendet und dann die Methoden hinzufügen, die ich will ..? – user319045

+0

@ user319045, Um eine Unterklasse zu erstellen, schreiben Sie einfach Ihr eigenes Modul, das eine neue Klasse mit der Syntax 'class SomeName (othermodule.TheClassYouAreExtending) erzeugt: ...' und 'SomeName' hängt wieder von der ursprünglichen Klasse ab. definierter Weg. Dies wird als * Vererbung * bezeichnet und entspricht normalerweise dem Hinzufügen von Methoden zu einer Klasse. Dieses und andere Themen werden in http://tinyurl.com/thinkcspy2e behandelt, einem Buch, das Sie in Python und OOP einführen wird. Es ist kostenlos online und im Druck verfügbar und ist besser als einige der anderen Optionen, die ich gesehen habe. –

+0

Das offizielle Tutorial http://docs.python.org/tut/ ist auch ziemlich gut, kann sich aber für Leute, die keine erfahrenen Programmierer mit einem guten Verständnis der verwendeten Programmierparadigmen sind, als schwieriger erweisen. –

1

Darf ich vorschlagen, das Rad hier nicht neu zu erfinden? Ich baue seit 2 Monaten einen> 6k Line Twitter Client, zuerst habe ich auch Python-twitter überprüft, aber es ist viel hinter den jüngsten API-Änderungen zurückgeblieben. Die Entwicklung scheint auch nicht so aktiv zu sein, auch da war es (zumindest bei der letzten Überprüfung) keine Unterstützung für OAuth/xAuth).

Also um ein bisschen nach der Suche mehr entdeckte ich tweepy:
http://github.com/joshthecoder/tweepy

Vorteile: Die aktive Entwicklung, OAauth/XAUTH und sich mit der API auf dem Laufenden.
Die Chancen stehen hoch, dass das, was Sie brauchen, bereits da ist.

Also mit, dass ich schlage vor, es für mich funktioniert, das einzige, was ich hinzufügen musste, war XAUTH (die zurück bekam fusionieren zu tweepy :)

Oh eine schamlose Stecker, wenn Sie Tweets analysieren müssen und/oder formatieren zu HTML meine python-Version der twitter-text- * Bibliotheken verwenden:
http://github.com/BonsaiDen/twitter-text-python

Diese Sache ist unittestetd ein garantiertes Tweets zu analysieren, wie Twitter.com tut es.

+0

Danke, ich habe mir Tweepy angeschaut, ich scheine einfach den Stil von Python-Twitter besser zu mögen. Ich baue keinen Twitter-Client, nur eine Tool-Suite, die einige Dinge sehr gut in Bezug auf die Forschung handhaben kann. – user319045

2

Angenommen, Sie haben ein älteres Modul mod, die Sie wie folgt verwenden genannt:

import mod 

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

Und Sie wollen, sie zu verlängern, ohne dass es für die Benutzer zu ersetzen. Einfach gemacht. Sie können Ihrem neuen Modul einen anderen Namen geben, newmod.py, oder es unter demselben Namen auf einem tieferen Pfad platzieren und denselben Namen beibehalten, z. /path/to/mod.py. Dann können Ihre Benutzer es in einem der folgenden Wege importieren:

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

oder

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

In Ihrem Modul, sollten Sie alle alten Namen zur Verfügung stellen:

from mod import * 

oder nennen Sie jeden importierten Namen explizit:

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 

Ich denke, die import * wird für diesen Anwendungsfall wartungsfreundlicher sein - wenn das Basismodul die Funktionalität erweitert, werden Sie nahtlos Schritt halten (obwohl Sie neue Objekte mit dem gleichen Namen schattieren könnten).

Wenn die mod Sie erweitern, hat eine anständige __all__, wird es die importierten Namen beschränken.

Sie sollten auch einen __all__ deklarieren und es mit dem erweiterten Modul __all__ erweitern.

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) 

Dann erweitern Sie die Objekte und Funktionen wie gewohnt.

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

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

Wenn die neuen Objekte Funktionalität anbieten wollen Sie ersetzen (oder vielleicht sind Zurückportieren Sie die neue Funktionalität in einem älteren Code-Basis) können Sie die Namen überschreiben können