# Python 运算符

> 原文： [http://zetcode.com/lang/python/operators/](http://zetcode.com/lang/python/operators/)

在 Python 编程教程的这一部分中，我们介绍了 Python 运算符。

运算符是特殊符号，表示已执行某个过程。 编程语言的运算符来自数学。 应用处理数据。 运算符用于处理数据。

在 Python 中，我们有几种类型的运算符：

*   算术运算符
*   布尔运算符
*   关系运算符
*   按位运算符

一个运算符可以有一个或两个操作数。 操作数是运算符的输入（参数）之一。 仅使用一个操作数的那些运算符称为一元运算符。 那些使用两个操作数的对象称为二进制运算符。

+和-可以是加减运算符，也可以是一元符号运算符。 这取决于实际情况。

```py
>>> 2
2
>>> +2
2
>>> 

```

加号可以用来表示我们有一个正数。 但是它通常不被使用。 减号更改值的符号。

```py
>>> a = 1
>>> -a
-1
>>> -(-a)
1

```

乘法和加法运算符是二进制运算符的示例。 它们与两个操作数一起使用。

```py
>>> 3 * 3
9
>>> 3 + 3
6

```

## Python 赋值运算符

赋值运算符`=`将值赋给变量。 在数学中，`=`运算符具有不同的含义。 在等式中，`=`运算符是一个相等运算符。 等式的左侧等于右侧。

```py
>>> x = 1
>>> x
1

```

在这里，我们为`x`变量分配一个数字。

```py
>>> x = x + 1
>>> x
2

```

先前的表达式在数学上没有意义。 但这在编程中是合法的。 该表达式意味着我们向`x`变量加 1。 右边等于 2，并且 2 分配给`x`。

```py
>>> a = b = c = 4
>>> print(a, b, c)
4 4 4

```

可以为多个变量分配一个值。

```py
>>> 3 = y
  File "<stdin>", line 1
SyntaxError: can't assign to literal

```

此代码示例导致语法错误。 我们无法为字面值分配值。

## Python 算术运算符

下表是 Python 编程语言中的算术运算符表。

| 符号 | 名称 |
| --- | --- |
| `+` | 加成 |
| `-` | 减法 |
| `*` | 乘法 |
| `/` | 除法 |
| `//` | 整数除法 |
| `%` | 模数 |
| `**` | 乘方 |

以下示例显示了算术运算。

`arithmetic.py`

```py
#!/usr/bin/env python

# arithmetic.py

a = 10
b = 11
c = 12

add = a + b + c
sub = c - a
mult = a * b
div = c / 3

power = a ** 2

print(add, sub, mult, div)
print(power)

```

所有这些都是数学上已知的运算符。

```py
$ ./arithmetic.py 
33 2 110 4.0
100

```

共有三位运算符负责部门划分。

`division.py`

```py
#!/usr/bin/env python

# division.py

print(9 / 3)
print(9 / 4)
print(9 // 4)
print(9 % 4)

```

该示例演示了除法运算符。

```py
print(9 / 4)

```

结果为 2.25。 在 Python 2.x 中，`/`运算符是整数除法运算符。 这在 Python 3 中已更改。在 Python 3 中，`/`运算符返回一个十进制数。

```py
print(9 // 4)

```

`//`运算符是 Python 3 中的整数运算符。

```py
print(9 % 4)

```

`%`运算符称为模运算符。 它找到一个数除以另一个的余数。 `9 % 4`，9 模 4 为 1，因为 4 两次进入 9 且余数为 1。

```py
$ ./division.py 
3.0
2.25
2
1

```

```py
>>> 'return' + 'of' + 'the' + 'king'
'returnoftheking'

```

加法运算符还可用于连接字符串。

```py
>>> 3 + ' apples'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

```

我们不能添加整数和字符串。 这导致`TypeError`。

```py
>>> str(3) + ' apples'
'3 apples'

```

为了使示例生效，必须使用`str()`函数将数字转换为字符串。

另一方面，乘法运算符可以与字符串和数字一起使用。

```py
>>> 'dollar ' * 5
'dollar dollar dollar dollar dollar '

```

## Python 布尔运算符

在 Python 中，我们具有`and`，`or`和`not`布尔运算符。 使用布尔运算符，我们可以执行逻辑运算。 这些最常与`if`和`while`关键字一起使用。

`andop.py`

```py
#!/usr/bin/env python

# andop.py

print(True and True)
print(True and False)
print(False and True)
print(False and False)

```

此示例显示了逻辑和运算符。 仅当两个操作数均为`True`时，逻辑和运算符才对`True`求值。

```py
$ ./andop.py 
True
False
False
False

```

如果两个操作数中的任何一个为`True`，则逻辑或运算符求值为`True`。

`orop.py`

```py
#!/usr/bin/env python

# orop.py

print(True or True)
print(True or False)
print(False or True)
print(False or False)

```

如果运算符的一方为`True`，则操作的结果为`True`。

```py
$ ./orop.py 
True
True
True
False

```

否定运算符`not`使`True` `False`和`False` `True`。

`negation.py`

```py
#!/usr/bin/env python

# negation.py

print(not False)
print(not True)
print(not ( 4 < 3 ))

```

该示例显示了`not`运算符的作用。

```py
$ ./negation.py 
True
False
True

```

并且，或者对短路进行了求值。 短路求值意味着仅当第一个参数不足以确定表达式的值时，才求值第二个参数：当和的第一个参数求值为`false`时，总值必须为`false`； 当或的第一个参数为`true`时，总值必须为`true`。

以下示例演示了简短的短路求值。

`short_circuit.py`

```py
#!/usr/bin/env python

# short_circuit.py

x = 10
y = 0

if (y != 0 and x/y < 100):
      print("a small value")

```

表达式的第一部分计算为`False`。 表达式的第二部分不计算。 否则，我们将得到`ZeroDivisionError`。

## Python 关系运算符

关系运算符用于比较值。 这些运算符总是产生布尔值。

| 符号 | 含义 |
| --- | --- |
| `<` | 小于 |
| `<=` | 小于或等于 |
| `>` | 大于 |
| `>=` | 大于或等于 |
| `==` | 等于 |
| `!=` | 不等于 |
| `is` | 对象身份 |
| `is not` | 否定对象身份 |

上表显示了 Python 关系运算符。

```py
>>> 3 < 4
True
>>> 4 == 3
False
>>> 4 >= 3
True

```

如前所述，关系运算符返回布尔值：`True`或`False`。

注意，关系运算符不限于数字。 我们也可以将它们用于其他对象。 尽管它们可能并不总是有意义的。

```py
>>> "six" == "six"
True
>>> 'a' < 'b'
True

```

我们也可以比较字符串对象。

```py
>>> 'a' < 'b'

```

这里到底发生了什么？ 计算机不知道字符或字符串。 对于他们来说，一切都只是数字。 字符是存储在特定表中的特殊数字，例如 ASCII。

```py
>>> 'a' > 6
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() > int()

```

在不同的数据类型上不能使用关系运算符。 该代码导致一个`TypeError`。

`compare.py`

```py
#!/usr/bin/env python

# compare.py

print('a' < 'b')

print("a is:", ord('a'))
print("b is:", ord('b'))

```

在内部，a 和 b 字符是数字。 因此，当我们比较两个字符时，我们将比较它们的存储数字。 内置的`ord()`函数返回单个字符的 ASCII 值。

```py
$ ./compare.py 
True
a is: 97
b is: 98

```

实际上，我们比较两个数字：97 和 98。

```py
>>> "ab" > "aa"
True

```

假设我们有一个包含更多字符的字符串。 如果前几个字符相等，我们将比较下一个字符。 在我们的情况下，第二个位置的`b`字符的值比`a`字符大。 这就是为什么`"ab"`字符串大于`"aa"`字符串的原因。 当然，以这种方式比较字符串没有多大意义。 但这在技术上是可能的。

## Python 对象身份运算符

对象标识运算符`is`和`not is`检查其操作符是否是同一对象。

`object_identity.py`

```py
#!/usr/bin/env python

# object_identity.py

print(None == None)
print(None is None)

print(True is True)

print([] == [])
print([] is [])

print("Python" is "Python")

```

`==`运算符测试是否相等，而`is`运算符测试对象身份。 我们是否在谈论同一对象。 请注意，更多变量可能引用同一对象。

```py
$ ./object_identity.py 
True
True
True
True
False
True

```

输出可能会让您感到惊讶。 在 Python 语言中，只有一个`None`和一个`True`对象。 这就是`True`相等且与`True`相同的原因。 无论如何，那里只有一个真理。 空列表`[]`等于另一个空列表`[]`。 但是它们并不相同。 Python 已将它们放入两个不同的内存位置。 它们是两个不同的对象。 因此，`is`运算符返回`False`。

另一方面，`"Python"`是`"Python"`返回`True`。 这是由于优化：如果两个字符串字面值相等，则将它们放置在相同的内存位置。 由于字符串是不可变的实体，因此不会造成任何伤害。

## Python 成员运算符

成员运算符`in`和`not in`测试序列中的成员性，例如字符串，列表或元组。

`membership.py`

```py
#!/usr/bin/env python

# membership.py

items = ("coin", "book", "pencil", "spoon", "paper")

if "coin" in items:
    print("There is a coin in the tuple")
else:
    print("There is no coin in the tuple")

if "bowl" not in items:
    print("There is no bowl in the tuple")
else:
    print("There is a bowl in the tuple")

```

通过成员运算符，我们可以测试元组中是否存在某个项目。

```py
if "coin" in items:

```

使用`in`运算符，我们检查`items`元组中是否存在`"coin"`。

```py
if "bowl" not in items:

```

使用`not in`运算符，我们检查`items`元组中是否不存在`"bowl"`。

```py
$ ./membership.py 
There is a coin in the tuple
There is no bowl in the tuple

```

这是示例的输出。

## Python 三元运算符

三元运算符是一个简单的条件分配语句。

```py
exp1 if condition else exp2

```

如果条件为`true`，则对`exp1`求值并返回结果。 如果条件为假，则求值`exp2`并返回其结果。

`ternary.py`

```py
#!/usr/bin/env python

# ternary.py

age = 31

adult = True if age >= 18 else False

print("Adult: {0}".format(adult))

```

在许多国家，成年取决于您的年龄。 如果您的年龄超过特定年龄，则您已经成年。 对于三元运算符，这是一种情况。

```py
adult = True if age >= 18 else False

```

首先求值条件。 如果年龄大于或等于 18，则返回`True`。 如果不是，则返回`else`关键字后面的值。 然后，将返回的值分配给`adult`变量。

```py
$ ./ternary.py 
Adult: True

```

31 岁的成年人是成年人。

## Python 按位运算符

小数对人类是自然的。 二进制数是计算机固有的。 二进制，八进制，十进制或十六进制符号仅是相同数字的符号。 按位运算符使用二进制数的位。 我们有二进制逻辑运算符和移位运算符。 在 Python 等高级语言中很少使用按位运算符。

| 符号 | 含义 |
| --- | --- |
| `~` | 按位取反 |
| `^` | 按位异或 |
| `&` | 按位与 |
| <code>&#124;</code> | 按位或 |
| `<<` | 左移 |
| `>>` | 右移 |

按位取反运算符分别将 1 更改为 0，将 0 更改为 1。

```py
>>> ~7
-8
>>> ~-8
7

```

运算符恢复数字 7 的所有位。这些位之一还确定数字是否为负。 如果我们再一次对所有位取反，我们将再次得到 7。

按位，运算符在两个数字之间进行逐位比较。 仅当操作数中的两个对应位均为 1 时，位位置的结果才为 1。

```py
     00110
  &  00011
   = 00010

```

第一个数字是二进制表示法 6，第二个数字是 3，最终结果是 2。

```py
>>> 6 & 3
2
>>> 3 & 6
2

```

按位或运算符在两个数字之间进行逐位比较。 如果操作数中的任何对应位为 1，则位位置的结果为 1。

```py
     00110
  |  00011
   = 00111

```

结果为`00110`或十进制 7。

```py
>>> 6 | 3
7

```

按位互斥或运算符在两个数字之间进行逐位比较。 如果操作数中对应位中的一个或另一个（但不是全部）为 1，则位位置的结果为 1。

```py
     00110
  ^  00011
   = 00101

```

结果为`00101`或十进制 5。

```py
>>> 6 ^ 3
5

```

如前所述，Python 和其他高级语言很少使用按位运算符。 但是，在某些情况下会使用它们。 一个示例是掩码。 掩码是特定的位模式。 它确定是否设置了某些属性。

让我们举一个 GUI 编程的例子。

`bitwise_or.py`

```py
#!/usr/bin/env python

# bitwise_or.py

import wx

app = wx.App()
window = wx.Frame(None, style=wx.MAXIMIZE_BOX | wx.RESIZE_BORDER 
	| wx.SYSTEM_MENU | wx.CAPTION |	 wx.CLOSE_BOX)
window.Show(True)

app.MainLoop()

```

这是 wxPython 代码的一个小示例。 `wx.MAXIMIZE_BOX`，`wx.RESIZE_BORDER`，`wx.SYSTEM_MENU`，`wx.CAPTION`和`wx.CLOSE_BOX`是常数。 按位或运算符将所有这些常数添加到掩码中。 在我们的例子中，所有这些属性都是使用按位或运算符设置的，并应用于`wx.Frame`小部件。

最后，我们还有按位移位运算符。 按位移位运算符向右或向左移位。

```py
number << n : multiply number 2 to the nth power
number >> n : divide number by 2 to the nth power

```

这些运算符也称为算术移位。

```py
     00110
  >> 00001
   = 00011

```

我们将数字 6 的每个位向右移动。 等于将 6 除以 2。结果为`00011`或十进制 3。

```py
>>> 6 >> 1
3

```

```py
     00110
  << 00001
   = 01100

```

我们将数字 6 的每个位向左移动。 等于将数字 6 乘以 2。结果为`01100`或十进制 12。

```py
>>> 6 << 1
12

```

## Python 复合赋值运算符

复合赋值运算符由两个运算符组成。 他们是速记员。

```py
>>> i = 1
>>> i = i + 1
>>> i
2
>>> i += 1
>>> i
3

```

`+=`复合运算符是这些速记运算符之一。

其他复合运算符是：

```py
-=   *=   /=   //=   %=   **=   &=   |=   ^=   >>=   <<=

```

## Python 运算符优先级

运算符优先级告诉我们首先求值哪个运算符。 优先级对于避免表达式中的歧义是必要的。

以下表达式 28 或 40 的结果是什么？

```py
3 + 5 * 5

```

像数学中一样，乘法运算符的优先级高于加法运算符。 结果是 28。

```py
(3 + 5) * 5

```

要更改求值顺序，可以使用方括号。 方括号内的表达式始终首先被求值。

以下列表显示了 Python 中的运算符优先级。

```py
unary +  -  ~
**
*  /  %
+  -
>>  <<
&
^
|
<  <=  ==  >=  >  !=  is
not
and 
or

```

同一行上的运算符具有相同的优先级。 优先级从低到高。

`precedence.py`

```py
#!/usr/bin/env python

# precedence.py

print(3 + 5 * 5)
print((3 + 5) * 5)

print(2 ** 3 * 5)
print(not True or True)
print(not (True or True))

```

在此代码示例中，我们显示一些常见的表达式。 每个表达式的结果取决于优先级。

```py
print(2 ** 3 * 5)

```

幂运算符的优先级高于乘法运算符。 首先，对`2 ** 3`求值，返回 8。然后将结果乘以 5，结果为 40。

```py
print(not True or True)

```

在这种情况下，`not`运算符具有更高的优先级。 首先，将第一个`True`值取反为`False`，然后`or`运算符组合`False`和`True`，最后得到`True`。

```py
$ ./precedence.py 
28
40
40
True
False

```

关系运算符的优先级高于逻辑运算符。

`positive.py`

```py
#!/usr/bin/env python

# positive.py

a = 1
b = 2

if (a > 0 and b > 0):
   print("a and b are positive integers")

```

`and`运算符等待两个布尔值。 如果其中一个操作数不是布尔值，则会出现语法错误。 在 Python 中，关系运算符在逻辑与之前进行求值。

```py
$ ./positive.py 
a and b are positive integers

```

## Python 关联规则

有时，优先级不能令人满意地确定表达式的结果。 还有另一个规则称为关联性。 运算符的关联性确定优先级与相同的运算符的求值顺序。

```py
9 / 3 * 3

```

此表达式的结果是 9 还是 1？ 乘法，删除和模运算符从左到右关联。 因此，该表达式的计算方式为：`(9 / 3) * 3`，结果为 9。

算术，布尔，关系和按位运算符都是从左到右关联的。

另一方面，赋值运算符是正确关联的。

```py
>>> a = b = c = d = 0
>>> a, b, c, d
(0, 0, 0, 0)

```

如果关联从左到右，则以前的表达式将不可能。

复合赋值运算符从右到左关联。

```py
>>> j = 0
>>> j *= 3 + 1
>>> j
0

```

您可能期望结果为 1。但是实际结果为 0。由于有关联性。 首先求值右边的表达式，然后应用复合赋值运算符。

在本章中，我们讨论了 Python 中的运算符。