2010-04-24 26 views
14

¿Cuáles son las mejores prácticas para ampliar un módulo de python? En este caso, quiero extender python-twitter agregando nuevos métodos a la clase base de API.¿Cómo extiendo un módulo de Python? (python-twitter)

He visto tweepy, y también me gusta, me parece que python-twitter es más fácil de entender y ampliar con la funcionalidad que quiero.

Tengo los métodos ya escritos, solo estoy tratando de encontrar la mejor manera de agregarlos al módulo, sin cambiar el núcleo.

+0

Usted tiene que preguntarse qué es lo que está tratar de lograr eso no se puede resolver subclasando la funcionalidad del módulo existente. – jathanism

+0

hilo de interés en el grupo de noticias de Python sobre lo que estaba buscando originalmente que me llevó a esta sesión de preguntas y respuestas, el hilo es similar, hace 13 años: https://mail.python.org/pipermail/python-dev/2002-June /024839.html –

Respuesta

17

Algunas formas.

La forma más fácil:

no extienden el módulo, se extienden las clases.

exttwitter.py

import twitter 

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

Desventaja: Cada clase en Twitter debe estar en exttwitter.py, incluso si es sólo un talón (como el anterior)

Un duro (posiblemente un-Pythonic) manera:

Importe * desde python-twitter a un módulo que luego amplíe.

Por ejemplo:

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 

No estoy seguro de si el doble de importación en extmodule.py es python ic - podrías eliminarlo, pero luego no manejas el uso de querer extender una función que estaba en el espacio de nombres de basemodule.

En cuanto a las clases ampliadas, simplemente cree una nueva clase de API (basemodule.API) para extender el módulo API de Twitter.

+0

gracias, estaba buscando algo así para anular json.dumps sobre todo mi proyecto. (manteniendo las otras funciones) – njzk2

+0

No consideraría esto como antiponético. Son trucos útiles como este que pueden hacer que usar python sea tan poderoso. Solo sea obvio sobre lo que está haciendo. Intenta hacerlo en Java o C++ :-) – ThatAintWorking

6

No los agregue al módulo. Subclase las clases que desea extender y use sus subclases en su propio módulo, sin cambiar las cosas originales en absoluto.

+0

Ok, todavía no estoy familiarizado con la subclasificación en python (soy ingeniero, aún me estoy acostumbrando al estilo OO), ¿tiene algún recurso favorito? Entonces, básicamente, no hay nada especial sobre un módulo ... ¿Puedo simplemente escribir un nuevo módulo que use la clase de API python-twitter como clase base y luego agregar los métodos que quiero ...? – user319045

+0

@ user319045, Para crear la subclase, debe escribir su propio módulo que crea una nueva clase con la sintaxis 'class SomeName (othermodule.TheClassYouAreExtending): ...' y 'SomeName' dependerá de la clase original en un pozo- forma definida. Esto se llama * inheritance * y es la forma en que normalmente agregaría métodos a una clase. Este y otros temas están cubiertos en http://tinyurl.com/thinkcspy2e, que es un libro que le presentará a Python y OOP. Está disponible en línea y de forma gratuita, y es mejor que algunas de las otras opciones que he visto. –

+0

El tutorial oficial http://docs.python.org/tut/ también es bastante bueno, pero puede resultar más difícil para las personas que no son programadores experimentados con una buena comprensión de los paradigmas de programación que están utilizando. –

1

¿Puedo sugerir que no reinvente la rueda aquí? Estoy construyendo un cliente de Twitter de> 6k líneas durante 2 meses, al principio también miré python-twitter, pero está retrasado mucho con respecto a los cambios recientes de API. El desarrollo tampoco parece ser tan activo, también hubo (al menos la última vez que lo verifiqué) no hay soporte para OAuth/xAuth).

Así que después de buscar en torno a un poco más descubrí tweepy:
http://github.com/joshthecoder/tweepy

Pros: El desarrollo activo, OAauth/XAUTH y hasta la fecha con la API.
Hay muchas posibilidades de que lo que necesita ya esté allí.

por lo que sugiero ir con eso, está funcionando para mí, lo único que tenía que añadir era XAUTH (que consiguió unir de nuevo a tweepy :)

Oh un un enchufe descarado, si usted necesita para analizar los Tweets y/o darles formato HTML a utilizar mi versión pitón de las bibliotecas * twitter-texto-:
http://github.com/BonsaiDen/twitter-text-python

Esta cosa es un unittestetd garantizada para analizar los Tweets al igual que lo hace Twitter.com.

+0

Gracias, he visto a tweepy, parece que me gusta más el estilo de python-twitter. No estoy creando un cliente de Twitter, solo un conjunto de herramientas para manejar algunas cosas muy bien con respecto a la investigación. – user319045

2

Digamos que tiene un módulo más antiguo llamado mod que utilice la siguiente manera:

import mod 

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

Y usted desee para ampliarlo, sin reemplazarlo para sus usuarios. Hecho facilmente Puede darle a su nuevo módulo un nombre diferente, newmod.py o colocarlo con el mismo nombre en una ruta más profunda y mantener el mismo nombre, p. /path/to/mod.py. A continuación, los usuarios pueden importar en cualquiera de estas maneras:

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

o

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

En su módulo, tendrá que hacer todos los viejos nombres disponibles:

from mod import * 

o nombre explícitamente cada nombre que importe:

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 

Creo que el import * será más fácil de mantener para este caso de uso: si el módulo base expande la funcionalidad, podrá mantenerse al día (aunque puede sombrear objetos nuevos con el mismo nombre).

Si el mod que está ampliando tiene un __all__ decente, restringirá los nombres importados.

También debe declarar un __all__ y extenderlo con el módulo extendido __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) 

Luego extienda los objetos y la funcionalidad como lo haría normalmente.

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

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

Si los nuevos objetos proporcionan funcionalidad tiene la intención de reemplazar (o tal vez usted está backporting la nueva funcionalidad en una base de código antiguo) puede sobrescribir los nombres