12
votes

Comment ajouter mes propres attributs personnalisés aux types de python intégrés existants? Comme une corde?

Je veux faire quelque chose comme ça ...

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


2 commentaires

Le type de chaînes est str , pas chaîne .


Vous pouvez définitivement! S'il vous plaît voir ma réponse: Stackoverflow.com/a/58027024/4511978


8 Réponses :


9
votes

En bref, vous ne pouvez pas. La voie python serait de sous-classer la chaîne et de travailler à partir de là.


4 commentaires

Les produits de sous-classement sont rarement utiles. Il est presque toujours préférable de faire des fonctions qui les utilisent ou, dans le cas de l'ajout d'un État, créent des cours avec une instance tout ce qui est intégré en tant qu'attribut.


La sous-classement dict pour mettre en œuvre un commandant, multidire, immutabledict ou combinaisons de celles-ci est très courante. De l'autre côté dict est une collection STR n'est pas.


@MikeGraham Je pense aussi que ce sous-classement est généralement une douleur (d'ajouter simplement une nouvelle méthode, etc.). J'aime comment .NET Les méthodes d'extension permettent au comportement souhaité en C # et espéraient quelque chose de similaire dans Python.


@wasatchwizard, puisque les fonctions non liées à toutes les fonctions sont si courantes dans Python, il a beaucoup de sens juste d'écrire une fonction à la place. Il a tendance à être beaucoup plus facile à lire que ce serait quelque chose comme une méthode d'extension et il est moins sujette de collision.



0
votes

Python ne prend pas en charge cette fonctionnalité.


0 commentaires

1
votes

vous ne le faites pas. Utilisez des dictionnaires distincts pour "attacher" (de manière logique) d'informations à des valeurs immuables telles que des chaînes ou des chiffres (la chaîne ou la valeur du numéro en tant que clé, la valeur correspondante de la valeur dictée).


0 commentaires

0
votes

Vous ne pouvez pas, ce n'est pas pythonique. Monkey-Patching n'est pas une caractéristique couramment utilisée de Python, donc pour la performance - je crois - des raisons pour lesquelles vous ne pouvez pas le faire sur les classes informatiques intégrées ou leurs instances.

En fait, il a son propre nom à Python: Poinçonnage de canard.


0 commentaires

2
votes

Pour faire cela, vous pouvez sousclure str .

Toutefois, tout en éventuellement possible, la plupart du temps que vous êtes de sous-classement de construction (tels que str ), vous consultez un type de relation "a-un", pas "est-a-a", Par conséquent, la composition doit être utilisée, pas l'héritage (ce qui signifie que vous devez créer une classe avec une chaîne en tant qu'attribut d'instance plutôt que sur la chaîne de sous-classe).


1 commentaires

Je vais devoir regarder plus dans ce que l'enfer attribut est, mais cela semble très sage.



3
votes

RUBY WAY:

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


0 commentaires

24
votes

sur CPPHon, vous pouvez utiliser CPPTHON pour accéder à la C-API de l'interprète, de cette façon, vous pouvez modifier des types intégrés au moment de l'exécution.

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()


5 commentaires

+1 pour l'information! Je suis curieux, étant un peu nouveau à Python, pourquoi vous ne voudriez pas faire cela dans la production. Merci


Vous devez également appeler pytype_modifié après avoir modifié la dicte interne du type, afin d'effacer le cache d'attribut MRO (ou quoi que ce soit appelé).


Il y a interdirefruit qui permet de corriger des objets intégrés sur plusieurs versions Python.


Cela pourrait ressembler à cela fonctionne, mais cela provoque en réalité une corruption de mémoire, car elle contourne le travail Type .__ SETATTR __ Pour maintenir des invariants internes. Par exemple, Cet extrait de code lié imprime le mauvais résultat sur le second Imprimer , puis segfault sur le quatrième impression . ( interdirefruit a les mêmes défauts.)


classe pyobject_head est redondant



1
votes

Voici une idée. Ce n'est pas parfait, car cela ne fonctionne pas pour toutes les cordes, mais cela pourrait être utile.

Pour définir des attributs d'une chaîne ou tout autre objet: xxx

Voici un exemple: xxx


0 commentaires