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 itemgetterf = 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