read - twitter python sentiment analysis
¿Cómo extiendo un módulo python? Añadiendo nuevas funcionalidades al paquete `python-twitter` (5)
¿Puedo sugerir no reinventar la rueda aquí? Estoy construyendo un cliente de Twitter de> 6k líneas durante 2 meses, al principio también revisé python-twitter, pero se está quedando muy por detrás de los cambios recientes en la API. El desarrollo tampoco parece estar tan activo, también hubo (al menos cuando lo verifiqué por última vez) no hay soporte para OAuth / xAuth).
Así que después de buscar un poco más descubrí tweepy:
http://github.com/joshthecoder/tweepy
Pros: Desarrollo activo, OAauth / xAuth y actualizado con la API.
Hay muchas posibilidades de que lo que necesitas ya esté allí.
Así que sugiero ir con eso, está funcionando para mí, lo único que tuve que agregar fue xAuth (que se fusionó de nuevo a tweepy :)
Oh, un enchufe desvergonzado, si necesitas analizar Tweets y / o formatearlos a HTML, usa mi versión en python de las bibliotecas de twitter-text- *:
http://github.com/BonsaiDen/twitter-text-python
Esto está garantizado para analizar Tweets tal como lo hace Twitter.com.
¿Cuáles son las mejores prácticas para extender un módulo Python existente? En este caso, quiero extender el paquete python-twitter
agregando nuevos métodos a la clase de API base.
He mirado a tweepy
, y eso también me gusta; Simplemente encuentro que python-twitter
más fácil de entender y ampliar con la funcionalidad que quiero.
Ya tengo los métodos escritos. Intento descubrir la forma más Pythonic y menos disruptiva de agregarlos al módulo del paquete python-twitter
, sin cambiar el núcleo de estos módulos.
Aquí le mostramos cómo puede manipular directamente la lista de módulos en tiempo de ejecución - alerta de spoiler: obtiene el tipo de módulo del módulo de 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
... entonces podrías usar una función así:
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__}")
… También puede crear su propia subclase de módulo, especificando types.ModuleType
como antecesor de su class
recientemente declarada, por supuesto; Nunca he encontrado personalmente esto necesario para hacer.
(Además, no es necesario que obtenga el tipo de módulo del módulo de types
; siempre puede hacer algo como ModuleType = type(os)
después de importar el sistema ModuleType = type(os)
específicamente esta fuente del tipo porque no es obvio; a diferencia de muchos de sus otros tipos incorporados, Python no ofrece acceso al tipo de módulo en el espacio de nombres global).
La acción real se encuentra en el sys.modules
, donde (si es intrépido) puede reemplazar los módulos existentes y agregar los nuevos.
De algunas maneras.
La manera fácil:
No extiendas el módulo, extiende 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 solo un código auxiliar (como se muestra arriba)
Una forma más dura (posiblemente untípica):
Importa * desde python-twitter a un módulo que luego extiendes.
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 la importación doble en extmodule.py es pythonic; puede eliminarlo, pero luego no maneja el uso de la base de datos para querer extender una función que estaba en el espacio de nombres de basemodule.
En cuanto a las clases extendidas, simplemente cree una nueva clase de API (basemodule.API) para extender el módulo de API de Twitter.
Digamos que tienes un módulo antiguo llamado mod
que usas así:
import mod
obj = mod.Object()
obj.method()
mod.function()
# and so on...
Y desea extenderlo, sin reemplazarlo para sus usuarios. Fácilmente hecho 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, por ejemplo, /path/to/mod.py
. Entonces sus usuarios pueden importarlo de cualquiera de estas formas:
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 tu módulo, querrás que todos los nombres antiguos estén 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 la import *
será más fácil de mantener para este caso de uso: si el módulo base expande la funcionalidad, se mantendrá al día (aunque puede sombrear nuevos objetos con el mismo nombre).
Si el mod
que está extendiendo 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 la funcionalidad que pretende reemplazar (o tal vez está realizando una copia de seguridad de la nueva funcionalidad en una base de código más antigua), puede sobrescribir los nombres
No los agregue al módulo. Subclasifique las clases que desea extender y use sus subclases en su propio módulo, sin cambiar las cosas originales en absoluto.