python 在python中扩展内置类

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/352537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 19:56:40  来源:igfitidea点击:

Extending builtin classes in python

pythonstringmonkeypatching

提问by UnkwnTech

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.

如何在 python 中扩展内置类?我想向 str 类添加一个方法。
我已经做了一些搜索,但我发现的只是较旧的帖子,我希望有人知道更新的内容。

采纳答案by S.Lott

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

回答by lll

One way could be to use the "class reopening" concept (natively existing in Ruby) that can be implemented in Python using a class decorator. An exemple is given in this page: http://www.ianbicking.org/blog/2007/08/opening-python-classes.html

一种方法是使用“类重新打开”概念(在 Ruby 中原生存在),该概念可以使用类装饰器在 Python 中实现。本页给出了一个例子:http: //www.ianbicking.org/blog/2007/08/opening-python-classes.html

I quote:

我引用:

I think with class decorators you could do this:

我认为使用类装饰器你可以这样做:

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

Implemented like this:

像这样实现:

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

回答by MVP

Assuming that you can not change builtin classes. To simulate a "class reopening" like Ruby in Python3 where __dict__is an mappingproxy object and not dict object :

假设您不能更改内置类。要在 Python3 中模拟像 Ruby 这样的“类重新打开”,其中__dict__是一个 mappingproxy 对象而不是 dict 对象:

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

I could also write a decorator function 'open' as well:

我也可以编写一个装饰器函数“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