初级运算符在各种编程语言中都存在,在 Python 语言中还有一些高级运算符,这些高级运算符并不是所有的编程语言都支持的。

成员运算符

  • 假设变量 val = "h", strone = "老鸟python",我们通过下面表格来了解成员运算符。




python 使用realsense_内存地址


  • 成员运算符运算的结果为布尔值,val 作为一个元素,可以是任何类型的对象,只要在 strone 中能找到 val,就会返回 True。
val = "hon"
strone = "老鸟Python"
print(val in strone)


身份运算符

  • 身份运算符判断的是两个变量指向的对象的内存地址是否相同,Python 语言用 id 函数来获取变量指向的对象内存地址,我们通过如下表格了解身份运算符。


python 使用realsense_python 使用realsense_02


  • 用身份运算符判断的是变量指向的对象的内存地址,要注意被不同变量指向的不同对象的值相等,对象内存地址不一定相等。
a = 5
aa = 5
b = 5.1
bb = 5.1
c = False
cc = False
d = None
dd = None
strone = "hello"
strtwo = "hello"
listone = [1, 2]
listtwo = [1, 2]
tupleone = (1, 2)
tupletwo = (1, 2)
tuplethree = (1, [2, 3])
tuplefour = (1, [2, 3])

print(a is aa)                  # True
print(b is bb)                  # True
print(c is cc)                  # True
print(d is dd)                  # True
print(strone is strtwo)         # True
print(listone is listtwo)       # False
print(tupleone is tupletwo)     # True
print(tuplethree is tuplefour)  # False


  • 注意:如上面代码,我们知道数字类型,布尔类型,NoneType 类型和字符串类型的值相同则 id 相同;list 类型的值相同而 id 不同;里面成员里面不含有变量的 tuple 类型对应的值相同则 id 相同,如果 tuple 里面的成员(或者成员的成员的...无限递归)出现有变量的话,虽然值相同,但 id 不同。 我们来好好分析一下:1.早期的 Python 解释器对布尔类型,数字类型,NoneType类型的变量都是通过分配不同的内存存储的,自从 Python 2.7 之后,解释器做了优化,所以那些类型只要值相同,所在的内存是同一个; 2.其实字符串类型的值是放在常量区,相同的字符串所在内存地址是一样的,也就是只要变量指向的字符串值相同,用的是同一块内存; 3.对于 list 类型所有的 Python 版本包括 Python 2 采用的都是一样的内存机制,就是无论 list 值是什么,在每一次创建的时候 Python 解释器都会重新分配一块内存; 4.对于 tuple 类型,Python 3.6(包括)之后的版本则会判断里面的成员(或者成员的成员的...无限递归)是否有变量,如果有的话则重新分配内存,否则共用一块内存,而 Python 2 采用的机制是只要创建一个新的 tuple 对象都会重新分配一块内存 。
  • 大家注意到,我们上面所举的例子都是右值赋值的方式,如果是变量赋值呢,我们看下如下代码。
a = 5
aa = a
b = 5.1
bb = b
c = False
cc = c
d = None
dd = d
strone = "hello"
strtwo = strone
listone = [1, 2]
listtwo = listone
tupleone = (1, 2)
tupletwo = tupleone
tuplethree = (1, [2, 3])
tuplefour = tuplethree

print(a is aa)                  # True
print(b is bb)                  # True
print(c is cc)                  # True
print(d is dd)                  # True
print(strone is strtwo)         # True
print(listone is listtwo)       # True
print(tupleone is tupletwo)     # True
print(tuplethree is tuplefour)  # True


  • 我只说一句:Python 解释器所有的变量之间赋值都是采用的浅拷贝方案,浅拷贝就是把赋值运算符=右边的变量里面所指向值的内存地址直接赋值给左边的变量。

三目运算符

  • 在其他语言(C,C++,Java)中三目运算符的表示方式是:判定条件? 为真时的结果: 为假时的结果。 在 python 语言中三目运算符的表示方式是:为真时的结果 if 判定条件 else 为假时的结果。
score = 59
print "ok" if score >= 60 else "no"  # no


运算符优先级

  • 当一个表达式中有多个不同种类的运算符时,要按运算符的优先级进行先后运算,我们通过如下表格了解运算符优先级。


python 使用realsense_运算符_03


  • 如果一条表达式中有多个不同种类型的运算符时,用小括号 () 括起来的先进行运算,总之我们没必要死记硬背这些运算符优先级。
sex = "man"
score = 59

print(score >= 60 or sex == "man")      # 糟糕的写法
print((score >= 60) or (sex != "man"))  # 不错的写法


  • 我们在写一个表达式的时候,尽量不要有多个不同种类型的运算符运算,避免代码可读性差,要把该表达式拆分多个只含有一个运算符的表达式。
sex = "man"
score = 59

print(score >= 60 or sex == "man")     # 糟糕的写法

scoreok = (score >= 60)
man = (sex == "man")
print(scoreok or man)                  # 很棒的写法


本节重要知识点

  • 本节课讲的运算符运算属于高级运算符,要深入理解运算的对象和结果。
  • 运算符优先级不要死记硬背,要学会写出可读性强的代码。

作业

虽然我们还没学 list 类型,但我认为你应该懂了,对于如下代码,猜一下输出值为多少,为什么?


mylist = ["hello", [1, 2], 2]
print("h" in mylist)
print("hello" in mylist)
print(1 in mylist)
print(2 in mylist)
print([1, 2] in mylist)