欢迎来到皮皮网网首页

【Linux工具源码】【要饭系统源码】【上直播源码】predicate源码

来源:函数源码用法 时间:2024-12-29 12:39:59

1.inspect使用
2.Flux和Mono的常用API源码分析
3.说说 Python 的元编程
4.Java基础学习之函数式编程Predicate接口(JDK8)
5.Python库介绍(一)——inspect

predicate源码

inspect使用

       在Linux平台上调试大型项目,如PyTorch、TVM、ONNX等,往往涉及到Python和C++的混合体,以及复杂的Linux工具源码模块、类间依赖。此时,仅凭代码很难分析出当前代码在运行时实际调用的是哪个文件中的哪段代码。inspect库则能有效解决这一问题,特别是对于Python终端环境,它能帮助定位代码所在文件位置,之后,用户需自行探索。

       inspect库的功能远不止于此,下面总结了其使用方法。inspect模块通常被称为“检查现场对象”,其核心在于“现场”二字,即当前运行的状态。该模块提供了一系列函数,以了解现场对象的状态,包括模块、类、实例、要饭系统源码函数和方法。

       inspect函数主要用于四个方面,只需记住一句核心用法:找文件源码。

       1. inspect.getmembers(object[, predicate]):获取指定对象的所有成员,以(name,value)对组成的列表形式返回。

       2. inspect.getdoc(object):获取指定对象的documentation信息。

       3. inspect.getcomments(object):获取指定对象的注释信息。

       4. inspect.getfile(object): 返回对象的文件名。

       5. inspect.getmodule(object):返回对象所属的模块名。

       6. inspect.getsourcefile(object):返回对象的Python源文件名(对于内置对象不适用)。

       7. inspect.getsourcelines(object):以行号+代码行的形式返回对象的Python源文件内容。

       8. inspect.getsource(object):以字符串形式返回对象的源代码。

       对于类与函数,inspect提供了以下功能:

       1. inspect.getclasstree(classes[, unique]):获取类层次结构。

       2. inspect.getargspec(func):获取函数参数规格。

       3. inspect.getargvalues(frame):获取给定帧中的参数值。

       4. inspect.formatargspec(args[, varargs, varkw, defaults, formatarg, formatvarargs, formatvarkw, formatvalue, join]):格式化参数规格描述。

       5. inspect.formatargvalues(args[, varargs, varkw, locals, formatarg, formatvarargs, formatvarkw, formatvalue, join]):格式化参数值描述。

       以上便是inspect库的主要功能与使用方法。通过合理运用这些功能,开发者能更高效地分析和调试大型项目中的复杂问题。

Flux和Mono的常用API源码分析

       Flux是一个响应式流,能够生成零个、上直播源码一个、多个或无限个元素。Flux的产生元素机制主要体现在Flux.just和Flux.empty两个方法上。Flux.just返回的FluxArray内部存储了一个数组,用来保存1个或多个数据,通过ArraySubscription传递给消费者。Flux.empty则返回了一个FluxEmpty实例,当收到消费者注册信号时,会调用Operators的complete方法,消费者会收到一个complete信号,除此之外没有任何操作。

       重复流通过创建一个FluxRepeatPredicate对象实现,这个对象在结束时会重新订阅Publisher,从而产生无限数量的流。doOnSignal方法提供了在框架中不消费数据或转变数据的机制,实际上是操作符FluxPeekFuseable,其peek onNext代码逻辑能大致理解其原理。

       Mono表示要么有一个元素,要么产生完成或错误信号的Publisher。其then方法有五个重载版本,实际上创建了一个MonoIgnorePublisher,通过源码可以发现,MonoIgnorePublisher将真正的图片交友 源码监听者封装为IgnoreElementsSubscriber,然后将事件源监听。Mono和Flux都有Create方法,用于创建对应的序列,Mono的create方法创建了MonoCreate对象,里面包含了MonoSink和一个消费者。Mono的then方法会忽略前面的onNext数据,只会传递给下游完成和错误的信号。then(Mono other)则创建了一个ThenIgnoreMain,并在所有操作完成之后开始下一个流的消费。

       Mono和Flux的Create方法创建的对象为MonoCreate和FluxCreate,其中包含了MonoSink或FluxSink和一个消费者。使用using方法可以实现try-with-resource机制,用于包装阻塞API。

       在响应式编程中,我们需要处理各种异常情况,确保异常能够传播到需要接收的地方。Publisher分为冷发布者和热发布者,冷发布者在没有订阅者时不会生成数据,而热发布者不论是否有订阅者都会生成数据。冷热发布者可以相互转换,例如使用defer将热操作符转换为冷操作符,或者使用ConnectableFlux将冷操作符转换为热操作符。在多播流中,hashmap源码导读一个Publisher可以同时给多个消费者提供数据,但只会收到一次的订阅。

       FluxPublish对象在publish方法中创建,传入参数包括缓存大小和被包装的队列,这表示了publish方法创建了一个FluxPublish对象。在subscribe阶段,FluxPublish内部的PublishSubscriber会添加到父容器中。在connect方法中,真正订阅数据源,随后PublishSubscriber的onSubscribe方法会执行,根据参数拉取数据,onNext方法处理接收到的数据。

       本文通过解析Flux和Mono的常用API,揭示了它们在响应式编程中的应用和原理,旨在帮助读者更好地理解并运用这些流式操作符。正确处理异常、理解冷热发布者之间的转换以及掌握多播流的特性,对于构建高效、灵活的数据流处理系统至关重要。

说说 Python 的元编程

       æåˆ°å…ƒè¿™ä¸ªå­—,你也许会想到元数据,元数据就是描述数据本身的数据,元类就是类的类,相应的元编程就是描述代码本身的代码,元编程就是关于创建操作源代码(比如修改、生成或包装原来的代码)的函数和类。主要技术是使用装饰器、元类、描述符类。

       æœ¬æ–‡çš„主要目的是向大家介绍这些元编程技术,并且给出实例来演示它们是怎样定制化源代码的行为。

       è£…饰器 装饰器就是函数的函数,它接受一个函数作为参数并返回一个新的函数,在不改变原来函数代码的情况下为其增加新的功能,比如最常用的计时装饰器:

from functools import wrapsdef timeit(logger=None):"""耗时统计装饰器,单位是秒,保留 4 位小数"""def decorator(func):@wraps(func)def wrapper(*args, **kwargs):start = time.time()result = func(*args, **kwargs)end = time.time()if logger:logger.info(f"{ func.__name__} cost { end - start :.4f} seconds")else:print(f"{ func.__name__} cost { end - start :.4f} seconds")return resultreturn wrapperreturn decorator

       (注:比如上面使用 @wraps(func) 注解是很重要的, 它能保留原始函数的元数据) 只需要在原来的函数上面加上 @timeit() 即可为其增加新的功能:

@timeit()def test_timeit():time.sleep(1)test_timeit()#test_timeit cost 1. seconds

       ä¸Šé¢çš„代码跟下面这样写的效果是一样的:

test_timeit = timeit(test_timeit)test_timeit()

       è£…饰器的执行顺序 当有多个装饰器的时候,他们的调用顺序是怎么样的?

       å‡å¦‚有这样的代码,请问是先打印 Decorator1 还是 Decorator2 ?

from functools import wrapsdef decorator1(func):@wraps(func)def wrapper(*args, **kwargs):print('Decorator 1')return func(*args, **kwargs)return wrapperdef decorator2(func):@wraps(func)def wrapper(*args, **kwargs):print('Decorator 2')return func(*args, **kwargs)return wrapper@decorator1@decorator2def add(x, y):return x + yadd(1,2)# Decorator 1# Decorator 2

       å›žç­”这个问题之前,我先给你打个形象的比喻,装饰器就像函数在穿衣服,离它最近的最先穿,离得远的最后穿,上例中 decorator1 是外套,decorator2 是内衣。

       add = decorator1(decorator2(add))

       åœ¨è°ƒç”¨å‡½æ•°çš„时候,就像脱衣服,先解除最外面的 decorator1,也就是先打印 Decorator1,执行到 return func(

       args, kwargs) 的时候会去解除 decorator2,然后打印 Decorator2,再次执行到 return func(

       args, kwargs) 时会真正执行 add() 函数。

       éœ€è¦æ³¨æ„çš„是打印的位置,如果打印字符串的代码位于调用函数之后,像下面这样,那输出的结果正好相反:

def decorator1(func):@wraps(func)def wrapper(*args, **kwargs):result = func(*args, **kwargs)print('Decorator 1')return resultreturn wrapperdef decorator2(func):@wraps(func)def wrapper(*args, **kwargs):result = func(*args, **kwargs)print('Decorator 2')return resultreturn wrapper

       è£…饰器不仅可以定义为函数,也可以定义为类,只要你确保它实现了__call__() 和 __get__() 方法。

       å…ƒç±» Python 中所有类(object)的元类,就是 type 类,也就是说 Python 类的创建行为由默认的 type 类控制,打个比喻,type 类是所有类的祖先。我们可以通过编程的方式来实现自定义的一些对象创建行为。

       å®šä¸€ä¸ªç±»ç»§æ‰¿ type ç±» A,然后让其他类的元类指向 A,就可以控制 A 的创建行为。典型的就是使用元类实现一个单例:

class Singleton(type):def __init__(self, *args, **kwargs):self._instance = Nonesuper().__init__(*args, **kwargs)def __call__(self, *args, **kwargs):if self._instance is None:self._instance = super().__call__(*args, **kwargs)return self._instanceelse:return self._instanceclass Spam(metaclass=Singleton):def __init__(self):print("Spam!!!")

       å…ƒç±» Singleton 的__init__和__new__ 方法会在定义 Spam 的期间被执行,而 __call__方法会在实例化 Spam 的时候执行。

       descriptor 类(描述符类)

       descriptor 就是任何一个定义了 __get__(),__set__()或 __delete__()的对象,描述器让对象能够自定义属性查找、存储和删除的操作。这里举官方文档[1]一个自定义验证器的例子。

       å®šä¹‰éªŒè¯å™¨ç±»ï¼Œå®ƒæ˜¯ä¸€ä¸ªæè¿°ç¬¦ç±»ï¼ŒåŒæ—¶è¿˜æ˜¯ä¸€ä¸ªæŠ½è±¡ç±»ï¼š

from abc import ABC, abstractmethodclass Validator(ABC):def __set_name__(self, owner, name):self.private_name = '_' + namedef __get__(self, obj, objtype=None):return getattr(obj, self.private_name)def __set__(self, obj, value):self.validate(value)setattr(obj, self.private_name, value)@abstractmethoddef validate(self, value):pass

       è‡ªå®šä¹‰éªŒè¯å™¨éœ€è¦ä»Ž Validator 继承,并且必须提供 validate() 方法以根据需要测试各种约束。

       è¿™æ˜¯ä¸‰ä¸ªå®žç”¨çš„数据验证工具:

       OneOf 验证值是一组受约束的选项之一。

class OneOf(Validator):def __init__(self, *options):self.options = set(options)def validate(self, value):if value not in self.options:raise ValueError(f'Expected { value!r} to be one of { self.options!r}')

       Number 验证值是否为 int 或 float。根据可选参数,它还可以验证值在给定的最小值或最大值之间。

class Number(Validator):def __init__(self, minvalue=None, maxvalue=None):self.minvalue = minvalueself.maxvalue = maxvaluedef validate(self, value):if not isinstance(value, (int, float)):raise TypeError(f'Expected { value!r} to be an int or float')if self.minvalue is not None and value < self.minvalue:raise ValueError(f'Expected { value!r} to be at least { self.minvalue!r}')if self.maxvalue is not None and value > self.maxvalue:raise ValueError(f'Expected { value!r} to be no more than { self.maxvalue!r}')

       String 验证值是否为 str。根据可选参数,它可以验证给定的最小或最大长度。它还可以验证用户定义的 predicate。

class String(Validator):def __init__(self, minsize=None, maxsize=None, predicate=None):self.minsize = minsizeself.maxsize = maxsizeself.predicate = predicatedef validate(self, value):if not isinstance(value, str):raise TypeError(f'Expected { value!r} to be an str')if self.minsize is not None and len(value) < self.minsize:raise ValueError(f'Expected { value!r} to be no smaller than { self.minsize!r}')if self.maxsize is not None and len(value) > self.maxsize:raise ValueError(f'Expected { value!r} to be no bigger than { self.maxsize!r}')if self.predicate is not None and not self.predicate(value):raise ValueError(f'Expected { self.predicate} to be true for { value!r}')

       å®žé™…应用时这样写:

@timeit()def test_timeit():time.sleep(1)test_timeit()#test_timeit cost 1. seconds0

       æè¿°å™¨é˜»æ­¢æ— æ•ˆå®žä¾‹çš„创建:

@timeit()def test_timeit():time.sleep(1)test_timeit()#test_timeit cost 1. seconds1

       æœ€åŽçš„话 关于 Python 的元编程,总结如下:

       å¦‚果希望某些函数拥有相同的功能,希望不改变原有的调用方式、不写重复代码、易维护,可以使用装饰器来实现。

       å¦‚果希望某一些类拥有某些相同的特性,或者在类定义实现对其的控制,我们可以自定义一个元类,然后让它类的元类指向该类。

       å¦‚果希望实例的属性拥有某些共同的特点,就可以自定义一个描述符类。

       ä»¥ä¸Šå°±æ˜¯æœ¬æ¬¡åˆ†äº«çš„所有内容,如果你觉得文章还不错,欢迎关注公众号:Python编程学习圈,每日干货分享,内容覆盖Python电子书、教程、数据库编程、Django,爬虫,云计算等等。或是前往编程学习网,了解更多编程技术知识。

原文:/post/

Java基础学习之函数式编程Predicate接口(JDK8)

       深入探讨函数式编程中的Predicate接口,作为Java基础学习的一部分。在实际应用中,该接口主要用于构建条件表达式。首先,我们从源码出发,揭示Predicate接口的核心。

       源码解析显示,Predicate接口仅包含一个抽象方法,并被@FunctionalInterface标注,确保其符合函数式编程的标准。

       让我们详细分析几个方法:

       1. **and** - 返回的匿名内部类逻辑相当于“与”运算,即两个条件同时满足时返回true,否则为false。举例:判断参数是否为偶数且大于,结果为false。这种设计简化了判断逻辑,便于复用。

       2. **negate** - 实现逻辑取反,对于原判断条件,返回其相反的结果。

       3. **or** - 逻辑“或”运算,只要两个条件中的一个为true,整体结果即为true。

       4. **isEqual** - 作为静态方法,用于创建一个比较特定对象的Predicate,提供灵活的条件组合。

       综上,Predicate接口是函数式编程中的重要工具,用于构建复杂的逻辑判断,其简洁性和复用性在实际开发中得到广泛应用。它体现了函数式编程的核心思想,即有输入,有明确输出,且注重逻辑的组合与复用。

       函数式编程的探索并未止步于此,接下来将继续深入学习Function接口,进一步扩展对函数式编程的理解与应用。

Python库介绍(一)——inspect

       本文旨在深入探讨Python中的inspect库,该库提供了一系列实用功能,用于获取活动对象的信息,包括模块、类、方法、函数、报错追踪、帧对象和代码对象。让我们先从官方文档入手,了解inspect库的基本功能和用途。

       官方文档介绍,inspect库提供了多种功能,如检查类的内容、检索方法的源代码、提取并格式化函数的参数列表、展示详细的traceback信息等。下面将重点介绍inspect库的主要方法和属性,以及相关对象的特性。

       主要方法和属性

       inspect.getmembers(object[,predicate]): 返回由object成员(name, value)构成的排序列表,根据name排序。若提供predicate参数,仅返回满足条件的成员。

       inspect.getmodulename(path): 通过输入路径返回模块名称。输入路径为package时返回None。

       inspect.ismodule(object): 判断object是否为module,返回True或False。

       inspect.isclass(object): 判断object是否为class,返回True或False。

       inspect.ismethod(object): 判断object是否为方法,返回True或False。

       此外,inspect库还包含一系列以“is”开头的方法和一系列以“get”开头的方法,具体细节可参考官方文档。

       Signature对象

       Signature对象代表可调用对象的调用签名和返回注解。使用signature()函数创建Signature对象。可调用对象(如函数和方法)可以通过内置函数callable()判断。

       下面展示了Signature对象的属性和方法:

       parameters: 返回有序字典,包含参数名和Parameter对象。

       return_annotation: 可调用对象的返回注解,无注解时返回Signature.empty。

       bind(*args, **kwargs): 根据参数构建BoundArguments实例。

       Parameter对象

       Parameter对象包含函数参数的信息,如参数名、默认值、注解等。Parameter对象不可修改,使用Parameter.replace()方法创建修改后的副本。

       empty: 无默认值时的Parameter实例。

       name: 参数名。

       default: 参数默认值。

       annotation: 参数注解。

       kind: 参数种类,以Parameter枚举值表示。

       BoundArguments对象

       BoundArguments对象用于表示函数调用时参数的绑定情况。与parameters和arguments不同,BoundArguments包含显式绑定的参数。

       arguments: 参数名到参数值的可变映射,随值变化动态更新。

       args: 位置参数值的元组。

       kwargs: 关键字参数值的字典。

       signature: 与函数关联的Signature对象。

       apply_defaults(): 设置默认参数。

       本文旨在提供对Python inspect库的深入理解,包括其功能、方法、属性及对象的使用。对于需要深入探索inspect库的读者,强烈建议查阅官方文档以获取更详细的指导。本文旨在提供一个概览,帮助读者在实际项目中有效利用inspect库。