【模块篇】operator的使用

146 阅读4分钟

operator 模块提供了一套与Python的内置运算符对应的高效率函数。例如,operator.add(x, y) 与表达式 x+y 相同。 许多函数名与特殊方法名相同,只是没有双下划线。为了向后兼容性,也保留了许多包含双下划线的函数。为了表述清楚,建议使用没有双下划线的函数。 函数包含的种类有:对象的比较运算、逻辑运算、数学运算以及序列运算

上面这段话引用了官方关于operator的定义,关于数学计算其实只是将一些表达式写入到了函数里面,所以本篇将不再对这些进行介绍。主要介绍一下一些有关对象操作的方法。

文章总览

获取对象的属性和方法

通过封装`attr`方法实现的获取可对对象的属性和方法的获取,通过`from operator import attrgetter`进行导入,可以在对象中进行查找所需的属性或方法,示例:
from operator import attrgetter
# f = attrgetter()  # attrgetter必须要存在一个参数
# f = attrgetter("name", 10)  # attrgetter的参数只能是字符串
f = attrgetter("name")
print(f)
g = attrgetter("name", "age", "sex")

attrgetter的参数必须要有一个,如果有多个则用,进行分割,必须是字符串。

from operator import attrgetter
class people:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def run(self):
        print("hello")
P = people("张三", 18)
f = attrgetter("name")
g = attrgetter("name", "age", "sex", "run")
f1 = f(P)
print(f1)
try:
    g1 = g(P)
except Exception as e:
    print(e)
h = attrgetter("name", "age", "run")
h1 = h(P)
print(h1)
张三
'people' object has no attribute 'sex'
('张三', 18, <bound method people.run of <__main__.people object at 0x000001D873E4DB70>>)

使用attrgetter可以获得对象中的属性(方法也一样可以),但是如果属性或者方法在对象中不存在的情况下(如 P.sex),则报错。

源代码

class attrgetter:
    """
    Return a callable object that fetches the given attribute(s) from its operand.
    After f = attrgetter('name'), the call f(r) returns r.name.
    After g = attrgetter('name', 'date'), the call g(r) returns (r.name, r.date).
    After h = attrgetter('name.first', 'name.last'), the call h(r) returns
    (r.name.first, r.name.last).
    """
    __slots__ = ('_attrs', '_call')

    def __init__(self, attr, *attrs):
        if not attrs:
            if not isinstance(attr, str):
                raise TypeError('attribute name must be a string')
            self._attrs = (attr,)
            names = attr.split('.')
            def func(obj):
                for name in names:
                    obj = getattr(obj, name)
                return obj
            self._call = func
        else:
            self._attrs = (attr,) + attrs
            getters = tuple(map(attrgetter, self._attrs))
            def func(obj):
                return tuple(getter(obj) for getter in getters)
            self._call = func

    def __call__(self, obj):
        return self._call(obj)

    def __repr__(self):
        return '%s.%s(%s)' % (self.__class__.__module__,
                              self.__class__.__qualname__,
                              ', '.join(map(repr, self._attrs)))

    def __reduce__(self):
        return self.__class__, self._attrs

获取字典对象的属性

通过`itemgetter`可以获取字典类型对象的属性,其使用方式与`attrgetter`相似,这里也不做过多介绍,示例代码如下,可以解决`d[key]`的获取。而`attrgetter`则是解决`p.x`的属性或方法的获取。 ```python from operator import itemgetter

f = itemgetter("name") g = itemgetter("name", "age", "sex", "run") h = itemgetter("name", "age") d = {"name":"张三", "age":18} print(f(d)) print(h(d)) try: print(g(d)) except Exception as e: print(e)

```text
张三
('张三', 18)
'sex'

源代码

class itemgetter:
    """
    Return a callable object that fetches the given item(s) from its operand.
    After f = itemgetter(2), the call f(r) returns r[2].
    After g = itemgetter(2, 5, 3), the call g(r) returns (r[2], r[5], r[3])
    """
    __slots__ = ('_items', '_call')

    def __init__(self, item, *items):
        if not items:
            self._items = (item,)
            def func(obj):
                return obj[item]
            self._call = func
        else:
            self._items = items = (item,) + items
            def func(obj):
                return tuple(obj[i] for i in items)
            self._call = func

    def __call__(self, obj):
        return self._call(obj)

    def __repr__(self):
        return '%s.%s(%s)' % (self.__class__.__module__,
                              self.__class__.__name__,
                              ', '.join(map(repr, self._items)))

    def __reduce__(self):
        return self.__class__, self._items

调用对象中的某个方法

通过`methodcaller`方法可以实现对某个方法的调用。函数构造如下: ```python def __init__(self, name, /, *args, **kwargs) ``` 其中`name`是位置参数,也是必须要填写的参数,`*args`、`**kwargs`是其余位置参数和关键字参数,属于选填内容。 ```python from operator import methodcaller class func: def run(self, x, y): return x + y class funcObj: def runObj(self, x, y): return x + y m = methodcaller("run", 5, y=8) # print(m(func)) # 不能直接操作类,而是操作类的实例 F = func() print(m(F)) try: FO = funcObj() print(m(FO)) except Exception as e: print(e) ``` ```text 13 'funcObj' object has no attribute 'run' ``` #### 源代码 ```python class methodcaller: """ Return a callable object that calls the given method on its operand. After f = methodcaller('name'), the call f(r) returns r.name(). After g = methodcaller('name', 'date', foo=1), the call g(r) returns r.name('date', foo=1). """ __slots__ = ('_name', '_args', '_kwargs')
def __init__(self, name, /, *args, **kwargs):
    self._name = name
    if not isinstance(self._name, str):
        raise TypeError('method name must be a string')
    self._args = args
    self._kwargs = kwargs

def __call__(self, obj):
    return getattr(obj, self._name)(*self._args, **self._kwargs)

def __repr__(self):
    args = [repr(self._name)]
    args.extend(map(repr, self._args))
    args.extend('%s=%r' % (k, v) for k, v in self._kwargs.items())
    return '%s.%s(%s)' % (self.__class__.__module__,
                          self.__class__.__name__,
                          ', '.join(args))

def __reduce__(self):
    if not self._kwargs:
        return self.__class__, (self._name,) + self._args
    else:
        from functools import partial
        return partial(self.__class__, self._name, **self._kwargs), self._args