扩展Python内置类

38 投票
4 回答
30371 浏览
提问于 2025-04-11 21:03

我该如何在Python中扩展一个内置类呢?
我想给字符串类(str)添加一个方法。
我查了一些资料,但找到的都是比较旧的帖子,希望有人能告诉我一些更新的信息。

4 个回答

7

假设你不能修改内置的类。为了在Python3中模拟像Ruby那样的“类重新开放”,这里的__dict__是一个mappingproxy对象,而不是一个字典对象:

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
18

一种方法是使用“类重开”的概念,这个概念在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
42

只需要创建这个类型的子类就可以了。

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

撰写回答