常量
值不可以变化的量,即为常量。因为种种原因,Python并未提供如C,C++,Java一样的const修饰符来声明常量,换言之,Python中没有声明常量的语法。Python程序一般通过约定俗成的变量名全大写的形式来表示这是一个常量(实际上还是变量)。
例如:
1
2
3
4
5
6
7
|
MYNAME = "Python" # 实际上,MYNAME还是一个变量。
print(type(MYNAME))
print(MYNAME)
MYNAME = 100
print(type(MYNAME))
print(MYNAME)
|
执行以上程序会输出如下结果:
1
2
3
4
|
<class 'str'>
Python
<class 'int'>
100
|
Python内置常量
Python内有一些内置常量(和前面介绍的大写表示的常量不同,内置常量的值是不可改变的),主要是以下。
False
bool类型,表示错误值。对False的赋值是非法的,并引发语法错误,抛出SyntaxError异常。
True
bool类型,表示正确值。对True的赋值是非法的,并引发语法错误,抛出SyntaxError异常。
None
NoneType类型的唯一的值。None通常用于表示缺少值,例如当默认参数未传递给函数时。对None的赋值是非法的,并引发语法错误,抛出SyntaxError异常。bool(None)结果是False。
NotImplemented
NotImplementedType类型,故名思议,就是“未实现”,一般是用在一些比较算法中的。如果二元比较算法(如__eq__(), __lt__(), __add__(), __rsub__(),__imul__(), __iand__()等)没有提供具体的比较实现时,应返回此值表示还没有实现。bool(NotImplemented)结果是True。
Ellipsis
与省略号文本”…“相同。主要与用户定义的容器数据类型的扩展切片语法一起使用的特殊值。bool(Ellipsis)结果是True。
这东西有啥用呢?据说它是Numpy的语法糖,不玩Numpy的人,可以说是没啥用的。在网上只看到用 “…” 代替 pass ,稍微有点用。
例如:
1
2
3
4
|
try:
1/0
except ZeroDivisionError:
... # 代替pass
|
debug
如果python不是以-o选项启动的,则此常量的值为是True。反之是False。
示例,打印内置常量的值和类型
1
2
3
4
5
6
7
8
9
10
11
12
|
print(False) # 输出 False
print(True) # 输出 True
print(None) # 输出 None
print(NotImplemented) # 输出 NotImplemented
print(Ellipsis) # 输出 Ellipsis
print(__debug__) # 输出 True
print(type(False)) # 输出 <class 'bool'>
print(type(True)) # 输出 <class 'bool'>
print(type(None)) # 输出 <class 'NoneType'>
print(type(NotImplemented))# 输出 <class 'NotImplementedType'>
print(type(Ellipsis)) # 输出 <class 'ellipsis'>
|
执行以上程序会输出如下结果:
1
2
3
4
5
6
7
8
9
10
11
|
False
True
None
NotImplemented
Ellipsis
True
<class 'bool'>
<class 'bool'>
<class 'NoneType'>
<class 'NotImplementedType'>
<class 'ellipsis'>
|
示例,内置常量的bool类型转换
1
2
3
4
5
6
|
print(bool(False)) # 输出False
print(bool(True)) # 输出True
print(bool(None)) # 输出False
print(bool(NotImplemented))# 输出True
print(bool(Ellipsis)) # 输出True
print(bool(__debug__)) # 输出True。如果Python是以-o选项启动的话,结果是False。
|
执行以上程序会输出如下结果:
1
2
3
4
5
6
|
False
True
False
True
True
True
|
示例,Ellipsis和…
1
2
3
4
5
6
7
8
9
|
# 比较Ellipsis和...
result = Ellipsis is ...
print(result) # 输出True
print(type(Ellipsis))
print(type(...))
print(bool(Ellipsis)) # 输出True
print(bool(...)) # 输出True
|
执行以上程序会输出如下结果:
1
2
3
4
5
|
True
<class 'ellipsis'>
<class 'ellipsis'>
True
True
|
注意: NotImplemented并不是异常,所以不能使用raise。当需要返回值时,应该是return NotImplemented。
我们看下面一个例子:
1
2
3
4
5
6
7
8
9
10
11
|
class Person:
def __init__(self, age):
self.age = age
def __eq__(self, other):
if not isinstance(other, Person):
return NotImplemented
return self.age == other.age
person = Person(10)
print(person == 10) # 输出False
|
为啥结果是false呢?
NotImplemented对象向运行时环境发出一个信号,告诉运行环境如果当前操作失败,它应该再检查一下其他可行方法。例如在 a == b 表达式,如果 a.__eq__(b) 返回 NotImplemented,那么 Python 会尝试 b.__eq__(a)。如果调用 b 的__eq__() 方法可以返回 True 或者 False,那么该表达式就成功了。如果 b.__eq__(a) 也不能得出结果,那么 Python 会继续尝试其他方法,例如使用 != 来比较。
person == 10,首先person.__eq__(10)返回NotImplemented,接下来10.__eq__(person)返回false。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
class Person:
def __init__(self, age):
self.age = age
def __eq__(self, other):
if not isinstance(other, Person):
return NotImplemented
return self.age == other.age
class Age:
def __init__(self, age):
self.age = age
def __eq__(self, other):
return self.age == other.age
person = Person(10)
age = Age(10)
print(person == age) # 输出True
|
首先person.__eq__(age)返回NotImplemented,接下来age.__eq__(person)返回True。
我们在写一些基础代码时,即使是没实现,也不要raise NotImplementedError,而是return NotImplemented,相当于提供给其它不同对象的比较接口,这对代码扩展非常有好处。
参考资料:
https://www.jianshu.com/p/23df8d592a31