为什么要使用操作员模块中的功能?

时间:2016-11-06 16:21:42

标签: python operators

python的operator模块有什么意义?那里有许多明显多余的功能,我不明白为什么人们更愿意使用这些功能而不是其他方式来做同样的事情。

例如:

>>> import operator
>>> operator.truth(0)
False
>>> bool(0)
False

似乎完全一样。

3 个答案:

答案 0 :(得分:7)

它有时可以访问运算符的功能,但作为一个函数。例如,要将两个数字相加,您可以这样做。

>> print(1 + 2)
3

您也可以

>> import operator
>> print(operator.add(1, 2))
3

函数方法的一个用例可能是你需要编写一个计算器函数,它给出一个简单公式的答案。

import operator as _operator

operator_mapping = {
    '+': _operator.add,
    '-': _operator.sub,
    '*': _operator.mul,
    '/': _operator.truediv,
}

def calculate(formula):
    x, operator, y = formula.split(' ')

    # Convert x and y to floats so we can perform mathematical
    # operations on them.
    x, y = map(float, (x, y))

    return operator_mapping[operator](x, y)

print(calculate('1 + 2'))  # prints 3.0

答案 1 :(得分:2)

完整性和一致性。因为在一个地方拥有所有操作员,您可以在以后进行动态查找:

fn main() {
    let mut u0 = U80 {data :0};
    let uval: u8 = 7;
    let ur0 = U8Ref { data: &uval };

    ur0.get();

    (&u0).get();

    u0.get();

    (&mut u0).get();
    {
        // Check that it works when U8Ref's reference outlives itself.
        let v = 0u8;
        let u: &u8;
        {
            let r = U8Ref { data: &v };
            u = r.get();
        }
        println!("{}", u);
    }
}

省略一些操作因为它们是多余的会破坏这个目的。并且因为Python名称只是引用,所以将getattr(operator, opname)(*arguments) 模块的名称添加到另一个引用中是很便宜且容易的。

答案 2 :(得分:1)

鉴于存在bool,现在很难想到operator.truth的任何用例。请注意,bool在2.2.1中是新的,并且运算符早于它,因此它可能仅出于历史原因而存在。运算符模块中还有其他无用的函数,例如operator.abs - 它只调用内置的abs

操作员模块有时对函数编程很有用。例如,Python有一个内置的sum函数,但忽略了包含一个类似的product函数。这可以通过使用运算符的乘法功能接口来实现:

>>> from operator import mul
>>> from functools import reduce 
>>> def product(sequence, start=1):
...     return reduce(mul, sequence, start)
... 
>>> product([7, 2, 3])
42

确实有其他方法可以实现这一点。可以说,程序方法,即使用普通的旧循环和用*运算符累加,更加pythonic。

对于因任何原因选择不使用命令式样式的用户,操作员模块提供比使用匿名函数更可口的实现

>>> timeit reduce(lambda x, y: x*y, range(1, 100))
10000 loops, best of 3: 24.3 µs per loop
>>> timeit reduce(mul, range(1, 100))
100000 loops, best of 3: 14.9 µs per loop

运营商C implementation(如果可用)提供的性能优于劣质lambda版本。运算符模块中提供的itemgetterattrgettermethodcaller函数还为通常由匿名函数处理的简单任务提供了更具可读性和更好性能的选项。