¿Cómo puedo extender un builtin clase en python?
Me gustaría añadir un método a la str de la clase.

He hecho algunas búsquedas, pero todo lo que estoy encontrando es de las entradas más antiguas, estoy esperando que alguien sepa de algo nuevo.

InformationsquelleAutor UnkwnTech | 2008-12-09

3 Comentarios

  1. 27

    Sólo subclase del tipo

    >>> class X(str):
    ...     def my_method(self):
    ...         return int(self)
    ...
    >>> s = X("Hi Mom")
    >>> s.lower()
    'hi mom'
    >>> s.my_method()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 3, in my_method
    ValueError: invalid literal for int() with base 10: 'Hi Mom'
    
    >>> z = X("271828")
    >>> z.lower()
    '271828'
    >>> z.my_method()
    271828
    • Tenía la esperanza de que no me han subclase pero después de poco más de investigación he llegado a la conclusión de que no es posible de ninguna otra manera, así que voy a aceptar esta respuesta.
    • No puedo imaginar una mejor manera de crear subclases. En serio. Lo que tenía en mente (monkeypatching?) nunca parece funcionar tan bien como una clara, precisa, obvio subclase.
    • Ruby clases abiertas y C#’s métodos de extensión vienen a la mente.
    • Conscientes de estos. Encontrar monkeypatching en todos los formularios a ser una gestión de pesadilla-que efectivamente prevenir la reutilización mediante la inyección de las características de oscuros caminos.
  2. 11

    Una forma podría ser la utilización de la «clase reapertura» concepto (de forma nativa existente en Ruby) que puede ser implementado en Python usando una clase decorator.
    Un ejemplo se da en esta página:
    http://www.ianbicking.org/blog/2007/08/opening-python-classes.html

    Cito:

    Creo que con la clase de decoradores que usted podría hacer esto:

    @extend(SomeClassThatAlreadyExists)
    class SomeClassThatAlreadyExists:
        def some_method(self, blahblahblah):
            stuff

    Implementado como este:

    def extend(class_to_extend):
        def decorator(extending_class):
            class_to_extend.__dict__.update(extending_class.__dict__)
            return class_to_extend
        return decorator
  3. 0

    Suponiendo que usted no puede cambiar builtin clases.
    Para simular una «clase reapertura» como Ruby en Python3 donde __dict__ es un mappingproxy objeto y no dict objeto :

    def open(cls):
      def update(extension):
        for k,v in extension.__dict__.items():
          if k != '__dict__':
            setattr(cls,k,v)
        return cls
      return update
    
    
    class A(object):
      def hello(self):
        print('Hello!')
    
    A().hello()   #=> Hello!
    
    #reopen class A
    @open(A)
    class A(object):
      def hello(self):
        print('New hello!')
      def bye(self):
        print('Bye bye')
    
    
    A().hello()   #=> New hello!
    A().bye()     #=> Bye bye

    Yo también podría escribir un decorador de la función «abrir» así:

    def open(cls):
      def update(extension):
        namespace = dict(cls.__dict__)
        namespace.update(dict(extension.__dict__))
        return type(cls.__name__,cls.__bases__,namespace)
      return update

Dejar respuesta

Please enter your comment!
Please enter your name here