Python 中的猴子修补内部类

问题描述 投票:0回答:1

我使用函数

lxml.etree.fromstring(str)
返回
lxml.etree._Element
的实例。我想为所有
lxml.etree._Element
对象添加一些便利功能,但似乎无法做到这一点。

这是我尝试过的方法和得到的错误:

import lxml

class CustomEtreeElement(lxml.etree._Element):

    def do_something_new(self):
        print('no problemo')

lxml.etree._Element = CustomEtreeElement


obj = lxml.etree.fromstring('<Foo><Bar>Baz</Bar></Foo>')

type(obj)
# <class 'lxml.etree._Element'>

obj.do_something_new()
# AttributeError: 'lxml.etree._Element' object has no attribute 'do_something_new'
python monkeypatching
1个回答
0
投票

在我看来,

lxml
对于创建继承来说有点过于复杂,因为据我了解,它是直接从C++导入方法,因此它们不是很透明。所以我会用
__getattr__
__getattribute__
添加类方法。了解它们并让我知道这个解决方案是否适合您。

下面我分享了一个可能解决您的问题的代码示例。

from typing import Any
import lxml


class CustomEtree():

    def __init__(self) -> None:
        self.etree = lxml.etree.fromstring('<Foo><Bar>Baz</Bar></Foo>')
        
    def __getattribute__(self, name: str) -> Any:
        
        if name == 'do_something_new':
            print ("new function")
            return lambda: 123
        
        return self.etree.get(name)
    

obj = CustomEtree()
obj.do_something_new() # 123
obj.fromstring('<Foo><Bar>Baz</Bar></Foo>') # do usual stuff

© www.soinside.com 2019 - 2024. All rights reserved.