¿Cómo agrego mis propios atributos personalizados a los tipos de Python incorporados existentes? ¿Como una cuerda?

Quiero hacer algo como esto …

def helloWorld(): print "Hello world!" str.helloWorld = helloWorld "foo".helloWorld() 

Lo que imprimiría “¡Hola mundo!”

EDITAR: Consulte ¿Puedo agregar métodos / atributos personalizados a los tipos de Python integrados?

En resumen, no puedes. El modo Python sería subclase de cadena y trabajo desde allí.

En CPython puede usar ctypes para acceder a la C-API del intérprete, de esta manera puede cambiar los tipos incorporados en tiempo de ejecución.

 import ctypes as c class PyObject_HEAD(c.Structure): _fields_ = [ ('HEAD', c.c_ubyte * (object.__basicsize__ - c.sizeof(c.c_void_p))), ('ob_type', c.c_void_p) ] _get_dict = c.pythonapi._PyObject_GetDictPtr _get_dict.restype = c.POINTER(c.py_object) _get_dict.argtypes = [c.py_object] def get_dict(object): return _get_dict(object).contents.value def my_method(self): print 'tada' get_dict(str)['my_method'] = my_method print ''.my_method() 

Aunque esto es interesante de ver y puede ser bastante interesante de descifrar … nunca lo use en código productivo. Solo haga una subclase del tipo incorporado o intente averiguar si hay otro, puede que sea un enfoque más pythonico para su problema.

Rubí forma:

 "1".to_i "1".to_roman 

Forma de python:

 int("1") Roman("1") # or Roman.fromstring("1") 

Donde Roman trabajará en una lista fija de tipos integrados o cualquier cosa con un método __int__ .

Es una limitación de la implementación de CPython que no puede establecer atributos de los tipos incorporados / de extensión. Se acompaña de una preferencia cultural para evitar la aplicación de parches a favor de funciones independientes, clases personalizadas que tienen como atributo el objeto deseado (o incluso la subclasificación en casos raros).

Para hacer eso puedes subclase str .

Sin embargo, si bien es técnicamente posible, la mayoría de las veces que crea subclases incorporados (como str ) está buscando un tipo de relación ‘has-a’, no ‘is-a’, por lo tanto, debe usarse la composición, no la herencia (es decir, debe crear una clase con una cadena como atributo de instancia, en lugar de una cadena de subclase).

Usted no Use diccionarios separados para “adjuntar” (lógicamente hablando) información a valores inmutables como cadenas o números (la cadena o valor numérico como clave, la información como valor correspondiente en el dict).

Python no admite esa función.

No puedes, no es Pythonic. El parcheo de monos no es una característica comúnmente utilizada de Python, por lo que para el rendimiento, creo, por las razones por las que no puede hacerlo en las clases integradas o instancias del mismo.

De hecho, tiene su propio nombre en Python: perforación de pato.

Aquí hay una idea. No es perfecto, porque no funciona para todas las cadenas, pero puede ser útil.

Para establecer los atributos de una cadena o cualquier otro objeto:

 def attr(e,n,v): #will work for any object you feed it, but only that object class tmp(type(e)): def attr(self,n,v): setattr(self,n,v) return self return tmp(e).attr(n,v) 

Aquí hay un ejemplo:

 >>> def helloWorld(): ... print("hello world!") #python 3 ... >>> a=attr("foo",'heloWorld',helloWorld) >>> a 'foo' >>> a.helloWorld() hello world! >>> "foo".helloWorld() Traceback (most recent call last): File "", line 1, in  "foo".helloWorld() AttributeError: 'str' object has no attribute 'helloWorld'