与 int 和 str 的乘法

Multiplication with int and str

我对这个看似简单的问题感到非常困惑。我想定义一个接受输入的函数,输入可以是 str 或 int 并将其加倍。例如,如果输入为 'foo',则输出将为 'foofoo'。同样,如果输入是 (9),输出将是 18。有人能指出我正确的方向吗?

这是我目前的情况:

def double(x):
    """returns two times a number if input is a number, returns double the size of the string inputted, if input is a string
str -> str; int -> int"""
    if x is :
        return x*2
    if x is :
        return x*2

怎么样:

def double(x):
    return x+x

def double(x):
    return x*2

两者都应作为:

  • 当参数是字符串时,+ 运算符被重载以执行连接;
  • 当一个参数是字符串时,* 运算符被重载为 "duplicate"。

由于 Python 是动态类型的,真正的 操作的选择将在 运行 时进行,具体取决于操作数的类型.


更正式地说,引用the documentation

The * (multiplication) operator yields the product of its arguments. The arguments must either both be numbers, or one argument must be an integer and the other must be a sequence. In the former case, the numbers are converted to a common type and then multiplied together. In the latter case, sequence repetition is performed; a negative repetition factor yields an empty sequence.

[...]

The + (addition) operator yields the sum of its arguments. The arguments must either both be numbers or both be sequences of the same type. In the former case, the numbers are converted to a common type and then added together. In the latter case, the sequences are concatenated.


如果你很好奇,从来源或 Python3.3.6/Objects/abstract.cPyNumber_Mul 的代码相当可比):

PyObject *
PyNumber_Add(PyObject *v, PyObject *w)
{
    PyObject *result = binary_op1(v, w, NB_SLOT(nb_add));
    if (result == Py_NotImplemented) {
        PySequenceMethods *m = v->ob_type->tp_as_sequence;
        Py_DECREF(result);
        if (m && m->sq_concat) {
            return (*m->sq_concat)(v, w);
        }
        result = binop_type_error(v, w, "+");
    }
    return result;
}

如您所见,解释器将首先尝试使用为左操作数定义的特殊方法 __add__ 执行加法。如果这个 returns NotImplemented,它将尝试将左操作数解释为一个序列并执行连接。

只需将输入乘以二即可。如果它是一个字符串,它将连接两次。如果是数字,则翻倍。

user = raw_input('Enter input: ')
print user * 2

查看 Python 文档。这是直接取自它。

Strings can be concatenated (glued together) with the + operator, and repeated with *:

>>> # 3 times 'un', followed by 'ium'
>>> 3 * 'un' + 'ium'
'unununium'