Как я могу расширить встроенный класс в python?
Я хотел бы добавить метод к классу str.
Я сделал некоторые поиски, но все, что я нахожу, это старые сообщения, я надеюсь, что кто-то знает что-то новое.
Расширение встроенных классов в python
Ответ 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
Надеюсь, вы найдете этот пост полезным.