Расширение встроенных классов в python

Как я могу расширить встроенный класс в python? Я хотел бы добавить метод к классу str.
Я сделал некоторые поиски, но все, что я нахожу, это старые сообщения, я надеюсь, что кто-то знает что-то новое.

Ответ 1

Просто подкласс типа

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

Ответ 2

Одним из способов может быть использование концепции "повторного открытия класса" (изначально существующей в Ruby), которая может быть реализована на Python с использованием декоратора класса. Пример приведен на этой странице: http://www.ianbicking.org/blog/2007/08/opening-python-classes.html

Я цитирую:

Я думаю, что с помощью декораторов классов вы можете сделать это:

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

Реализовано следующим образом:

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

Ответ 3

Предполагая, что вы не можете изменять встроенные классы. Чтобы имитировать "повторное открытие класса", например Ruby в Python3, где __dict__ - объект mappingproxy, а не dict object:

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

Я также мог бы написать функцию декоратора 'open':

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

Ответ 4

предполагая, что вы хотите расширить класс str, введя новый метод hellow_world(), вы можете сделать это следующим образом

>>> class my_string(str):
...     def hello_world(self):
...         print "Hello World"
... 
>>> s = my_string()
>>> s.hello_world()
Hello World

Если во вновь введенном методе вам нужно использовать методы из родительского класса, например, вы хотите определить метод double_count, который будет возвращать удвоенное число заданного символа, вы можете сделать

>>> class my_string(str):
...       def double_count(self, c):
...           return super(my_string, self).count(c) * 2 

>>> s = my_string("abcd")
>>> print s.double_count("a")
2

Надеюсь, вы найдете этот пост полезным.