36

How can I extend a builtin class in python? I would like to add a method to the str class.
I've done some searching but all I'm finding is older posts, I'm hoping someone knows of something newer.

4

3 に答える 3

36

Just subclass the type

>>> 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
于 2008-12-09T12:08:35.257 に答える
15

1 つの方法は、クラス デコレータを使用して Python で実装できる「クラスの再開」の概念 (Ruby にネイティブに存在する) を使用することです。このページに例が示されています: 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
于 2015-10-09T08:37:13.147 に答える
6

組み込みクラスを変更できないと仮定します。__dict__dict オブジェクトではなく mappingproxy オブジェクトである Python3の Ruby のような「クラスの再開」をシミュレートするには:

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

Python2 では、デコレータ関数「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
于 2016-09-26T17:39:31.107 に答える