你不知道的事:python的函数和对象本为一家

探讨了Python中函数和对象的关系,揭示了函数作为对象的特性,包括动态添加属性和方法,以及如何通过实现__call__方法使类实例可调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在文章神奇的python链式调用中,提到一个疑惑,函数和对象一样么

思考

  1. 一样的话说明函数也有属性,那么函数真的有么
  2. 函数和对象一样可以动态添加属性么
  3. 函数也是类的实例么
  4. 对象也可以调用么

def testFunc():
    pass

def testSubFunc():
    print('sub func!')

if __name__ == '__main__':
    # 动态加入属性
    testFunc.someAttr = 11
    print( testFunc.someAttr )
    # 动态加入方法
    testFunc.subFunc = testSubFunc
    # 调用动态加入的方法
    testFunc.subFunc()
    print( dir(testFunc) )
    print( type(testFunc) )

该例子中,我们定义了一个函数testFunc,如果函数和对象一样,那么第一点,他有属性,他还可以动态加入属性,包括静态属性和方法,于是我们进行了验证,输出如下:

11
sub func!
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'someAttr', 'subFunc']
<class 'function'>

由此可以看出,函数也是一个对象,他本身有很多的属性和方法,还能动态加入属性和方法,他是类function的一个实例。

那么对象也可以调用么?是的,类对象实现__call__方法后是可以直接调用的。

class testclass(object):
    def __call__(self):
        print('对象调用')
def testSubFunc():
    print('sub Func!')

if __name__ == '__main__':
    # 动态加入属性
    testclass.someAttr = 11
    print( testclass.someAttr )
    # 动态加入方法
    testclass.subFunc = testSubFunc
    # 调用动态加入的方法
    testclass.subFunc()
    print( dir(testclass) )
    print( type(testclass) )
    
    instance = testclass()
    instance()
    print(callable(testclass))

如上,定义类是重写了__call__方法,于是实例可以直接调用,当然call可以加入处理self以外的参数。

另外: 这和直接调用类不一样,直接调用类是创建实例,相关方法是init。也不能先实例化对象后,给对象添加call方法

可以直接调用的是一个callable对象,可以使用 callable(testclass)进行判断,可以直接调用的对象返回true,当然,函数返回的是true。

<think>嗯,用户想知道如何用XPath定位包含特定文本的元素。首先,我应该回忆一下XPath的基本语法。根据引用[2]提到的,XPath通过路径表达式来定位节点,其中包含元素属性。用户的问题是关于文本内容的,所以需要用到text()函数或者contains函数。 我记得contains函数可以用来部分匹配文本。比如,像//tag[contains(text(), '部分文字')]这样的结构。但要注意大小写敏感的问题。比如用户如果搜索“hello”,而实际文本是“Hello”,那就匹配上。可能需要提醒用户注意这点,或者建议使用translate函数来转换大小写。 另外,用户可能需要完全匹配的情况。这时候应该用text()='完整文字',过这种方式对空格换行敏感。比如如果元素内有换行或多余空格,可能无法匹配。这时候可能需要用normalize-space函数来处理,比如//tag[normalize-space(text())='完整文字'],这样可以忽略前后的空格。 还要考虑动态变化的部分文本,这时候contains函数就很有用,比如查找包含“更新”的日期文本。例如//span[contains(text(), '更新')]。 另外,引用[4]中的例子是//title[contains(text(), 'Rain')],这说明在处理文本时,contains结合text()是常见做法。同时,可能需要处理命名空间,但用户的问题里没有提到这点,可能暂时需要深入,但可以稍微提一下。 用户还可能遇到跨层级的文本内容,比如子元素包含文本,这时候可能需要用//div[.//text()[contains(., '目标文字')]],或者使用string()函数来获取整个节点的文本内容,再进行匹配。例如//div[contains(string(), '综合文本')]。 还有,XPath轴的使用,比如parent、child等,如引用[3]中的例子,过用户的问题主要是关于文本定位,可能暂时需要涉及轴,但可以作为扩展知识提到。 总结下来,需要分情况讨论:完全匹配、部分匹配、处理空格、跨层级文本,以及动态内容的情况。同时,给出具体的示例代码,比如使用lxml库的示例,这样用户可以直接应用。 最后,确保回答结构清晰,分点说明,并附上示例,这样用户能一步步理解应用。还要注意引用相关的参考资料,比如引用[2][4]中的内容,确保回答有依据。</think>### 如何通过 XPath 定位包含指定文本的节点 #### 1. **完全文本匹配** 若需精确匹配元素的完整文本内容,使用 `text()` 函数: ```xpath //标签名[text()='完整文字'] ``` **示例**:查找`<span>`标签中文本为“登录”的元素 `//span[text()='登录']` 注意:此方法对空格换行敏感,若文本存在额外空格需用 `normalize-space()` 处理: ```xpath //span[normalize-space(text())='登录'] ``` #### 2. **部分文本匹配** 使用 `contains()` 函数匹配包含特定子串的文本: ```xpath //标签名[contains(text(), '部分文字')] ``` **示例**:查找所有包含“更新”的`<div>`标签 `//div[contains(text(), '更新')]` 此方法常用于动态内容(如时间戳)的模糊匹配,例如`<div>最后更新:2024-06-30</div>`[^2] #### 3. **跨层级文本匹配** 若目标文本分布在子元素中,使用 `.` 表示当前节点下所有文本: ```xpath //父标签[contains(., '综合文本')] ``` **示例**:查找`<li>`标签下任意位置包含“优惠”的节点 `//li[contains(., '优惠')]` 适用于如 `<li><span>今日优惠</span>5折</li>` 的嵌套结构[^4] #### 4. **动态文本处理** 结合 `starts-with()` 或 `ends-with()` 处理规律性动态文本: ```xpath //a[starts-with(@href, '/detail') and contains(text(), '商品')] ``` **示例**:匹配以`/detail`开头且文本含“商品”的链接 `<a href="/detail/123">商品A介绍</a>` --- ### Python 代码示例(使用 lxml 库) ```python from lxml import html page_content = """ <html> <div class="news">今日新闻:系统升级公告</div> <p>更新时间:<span>2024-06-30</span></p> </html> """ tree = html.fromstring(page_content) # 查找包含"升级"的div nodes = tree.xpath('//div[contains(text(), "升级")]') print([n.text_content() for n in nodes]) # 输出: ['今日新闻:系统升级公告'] # 匹配更新时间文本 nodes = tree.xpath('//span[contains(., "2024")]') print([n.text.strip() for n in nodes]) # 输出: ['2024-06-30'] ``` --- ### 注意项 1. **大小写敏感**:XPath 默认区分大小写,可用 `translate()` 统一转为小写: ```xpath //*[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'hello')] ``` 2. **性能优化**:避免使用 `//` 开头的全路径搜索,尽量从最近父节点开始定位 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值