1.16 函数dir()
在Python程序中,如果函数dir()没有参数,则返回当前本地作用域内的名字列表。如果有参数,则尝试返回参数所指明对象的合法属性的列表。使用函数dir()的语法格式如下所示。
dir([object])
参数object是对象、变量或类型。如果参数object具有名为__dir__()的方法,那么将调用此方法,并且必须返回属性列表。这允许实现自定义__getattr__()或__getattribute__()函数的对象自定义dir()报告其属性的方式。如果参数object不提供__dir__(),则函数会尽量从对象的__dict__属性(如果已定义)和其类型对象中收集信息。结果列表不一定是完整的,并且当对象具有自定义__getattr__()时可能会不准确。具体来说,在使用函数dir()时,根据参数的不同会返回不同的结果,具体说明如下所示:
- 如果参数为空则返回当前作用域内的变量、方法和定义的类型列表;
- 当参数是一个模块时,会返回模块的属性、方法列表;
- 当参数是一个类时,会返回类及其子类的属性、方法列表;
- 当在参数对象中定义了__dir__方法时,则返回__dir__方法的结果。
在下面的实例文件dir.py中,演示了使用函数dir()返回指定列表的过程。
#当不传参数时,返回当前作用域内的变量、方法和定义的类型列表。
print(dir())
a = 10 #定义变量a
print(dir()) #多了一个a
#当参数对象是模块时,返回模块的属性、方法列表。
import math
print(math)
print(dir(math))
#当参数对象是类时,返回类及其子类的属性、方法列表。
class A:
name = 'class'
a = A()
print(dir(a))# name是类A的属性,其他则是默认继承的object的属性、方法
#当对象定义了__dir__方法,则返回__dir__方法的结果
class B:
def __dir__(self):
return ['name','age']
b = B()
print(dir(b))#调用 __dir__方法
执行后会输出:
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a']
<module 'math' (built-in)>
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']
['age', 'name']
1.17 函数divmod()
在Python程序中,函数divmod()的功能是把除数和余数运算结果结合起来,返回一个包含商和余数的元组(a // b, a % b)。在 python 2.3 版本之前,函数divmod()不允许处理复数。使用函数divmod()的语法格式如下所示。
divmod(a, b)
参数a和参数b都是数字,函数divmod()能够取两个(非复数)数字作为参数,并在使用整数除法时返回由商和余数组成的一对数字。对于混合的操作数类型参数,采用二元算术运算符的规则。对于整数参数来说,结果与(a // b, a % b)相同。对于浮点数参数来说,结果为(q, a % b),其中q通常为math.floor(a / b),也有可能比这个结果小1。不管怎样,q * b + a % b非常接近于a,如果a % b非0,它和b符号相同且0 <= abs(a % b) < abs(b)。
在下面的实例文件div.py中,演示了使用函数divmod()处理数字的过程。
# 如果参数都是整数,执行的是地板除,相当于 (a//b,a%b)。
print(divmod(5,2))
print(5//2)
print(5%2)
#如果参数时浮点数,相当于( math.floor(a/b),a%b)。
import math
print(divmod(5.5,2))
print(math.floor(5.5/2))
print(5.5/2)
print(math.floor(5.5/2.0))
print(5.5%2)
print(divmod(7, 2))
print(divmod(8, 2))
print(divmod(1+2j,1+0.5j))#有些python版本不允许处理复数
执行后会输出:
(2, 1)
2
1
(2.0, 1.5)
2
2.75
2
1.5
(3, 1)
(4, 0)
((1+0j), 1.5j)
有些Python版本不允许处理复数,文件div.py中的最后一行代码运行后可能会出错:
Traceback (most recent call last):
File " div.py", line 15, in <module>
print(divmod(1+2j,1+0.5j))
TypeError: can't take floor or mod of complex number.
1.18 函数enumerate()
在Python程序中,函数enumerate()的功能是将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般被用在 for 循环中。使用函数enumerate()的语法格式如下所示:
enumerate(sequence, [start=0])
- sequence:必须是一个序列、一个迭代器,或者其它某种支持迭代的对象;
- start:下标起始位置。
函数enumerate()会返回一个枚举对象,enumerate()返回的迭代器的__next__()方法返回一个元组,该元组包含一个计数(从start开始,默认为0)和迭代“sequence”得到的值。例如在下面的实例文件num.py中,演示了使用函数enumerate()处理数据的过程。
#基本用法
seasons = ['Spring', 'Summer', 'Fall', 'Winter']
print(list(enumerate(seasons)))
print(list(enumerate(seasons, start=1)))# 小标从 1 开始
#普通的 for 循环
i = 0
seq = ['one', 'two', 'three']
for element in seq:
print(i, seq[i])
i += 1
#在for循环使用 enumerate
seq = ['one', 'two', 'three']
for i, element in enumerate(seq):
print(i, seq[i])
#已知lst = [1,2,3,4,5,6],要求输出:
0,1
1,2
2,3
3,4
4,5
5,6
#
lst = [1,2,3,4,5,6]
for index,value in enumerate(lst):
print ('%s,%s' % (index,value))
#从指定索引从1开始
lst = [1,2,3,4,5,6]
for index,value in enumerate(lst,1):
print ('%s,%s' % (index,value))
#从指定索引从3开始
for index,value in enumerate(lst,3):
print ('%s,%s' % (index,value))
执行后会输出:
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
0 one
1 two
2 three
0 one
1 two
2 three
0,1
1,2
2,3
3,4
4,5
5,6
1,1
2,2
3,3
4,4
5,5
6,6
3,1
4,2
5,3
6,4
7,5
8,6
1.19 函数eval()
在Python程序中,函数eval()的功能是执行一个字符串表达式,并返回表达式的值。使用函数eval()的语法格式如下所示。
eval(expression, globals=None, locals=None)
- expression:表达式;
- globals:变量作用域,全局命名空间,如果被提供则必须是一个字典对象;
- locals:变量作用域,局部命名空间。如果有局部变量,则locals可以是任何映射类型对象。
在函数eval()中,参数“expression”被当作Python表达式来解析并演算(技术上来说,是个条件列表),使用globals和locals字典作为全局和局部的命名空间。如果globals字典存在,且缺少‘__builtins__’,在expression被解析之前,当前的全局变量被拷贝进globals。这说明expression通常具有对标准builtins的完全访问权限,并且传播受限环境。如果locals字典被忽略,则默认是globals字典。如果两个字典都省略,则在调用eval()的环境中执行表达式。返回值是被演算的表达式的结果。
在下面的实例文件eval.py中,演示了使用函数eval()处理字符串的过程。
x = 7
print(eval( '3 * x' ))
print(eval('pow(2,2)'))
print(eval('2 + 2'))
n=81
print(eval("n + 4"))
执行后会输出:
21
4
4
85
在Python程序中,当某行代码要使用变量 x 的值时,Python 会到所有可用的名字空间去查找变量,按照如下所示的顺序运行:
(1)局部名字空间:特指当前函数或类的方法。如果函数定义了一个局部变量 x, 或一个参数 x,Python 将使用它,然后停止搜索。
(2)全局名字空间:特指当前的模块。如果模块定义了一个名为x 的变量,函数或类,Python 将使用它然后停止搜索。
(3)内置名字空间:对每个模块都是全局的。作为最后的尝试,Python:将假设x是内置函数或变量。
在下面的实例文件eval1.py中,演示了使用函数eval()将字符串转成相应的对象(如list、tuple、dict和string之间的转换)的过程。
a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
b = eval(a)
print(b)
a = "{1:'xx',2:'yy'}"
c = eval(a)
print(c)
a = "(1,2,3,4)"
d = eval(a)
print(d)
执行后会输出:
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]
{1: 'xx', 2: 'yy'}
(1, 2, 3, 4)
在下面的实例文件eval2.py中,演示了使用反引号转换的字符串再反转回对象的过程。
list1 = [1,2,3,4,5]
print('list1')
'[1, 2, 3, 4, 5]'
print(type('list1'))
print(type(eval('list1')))
a = eval('list1')
print(a)
执行后会输出:
list1
<class 'str'>
<class 'list'>
[1, 2, 3, 4, 5]
1.20 函数exec()
在Python程序中,函数exec()的功能是执行储存在字符串或文件中的Python语句,和函数eval()相比,函数exec()可以执行更复杂的Python代码。使用函数exec()的语法格式如下所示。
exec(object[, globals[, locals]])
- object:必选参数,表示需要被指定的Python代码,必须是字符串或code对象。如果object是一个字符串,则该字符串会先被解析为一组Python语句,然后在执行(除非发生语法错误)。如果object是一个code对象,那么它只是被简单的执行;
- globals:可选参数,表示全局命名空间(存放全局变量),如果被提供,则必须是一个字典对象;
- locals:可选参数,表示当前局部命名空间(存放局部变量),如果被提供,可以是任何映射对象。如果该参数被忽略,那么它将会取与globals相同的值。
在下面的实例文件exec.py中,演示了使用函数exec()执行Python程序语句的过程。
# 单行语句字符串
exec('print("Hello World")')
exec("print ('runoob.com')")
#多行语句字符串
exec("""for i in range(5):
print ("iter time: %d" % i)
""")
x = 10
expr = """
z = 30
sum = x + y + z
print(sum)
"""
def func():
y = 20
exec(expr)
exec(expr, {'x': 1, 'y': 2})
exec(expr, {'x': 1, 'y': 2}, {'y': 3, 'z': 4})
func()
执行后会输出:
Hello World
runoob.com
iter time: 0
iter time: 1
iter time: 2
iter time: 3
iter time: 4
60
33
34