1.46 函数open()
在读取一个文件的内容之前,需要先打开这个文件。在Python程序中,可以通过内置函数open()来打开一个文件,并用相关的方法读或写文件中的内容供程序处理和使用,而且也可以将文件看作是Python中的一种数据类型。使用函数open()的语法格式如下所示。
open(file, mode='r', buffering=-l, encoding=None, errors=None, newline=None,closefd=True, opener=None)
- file:表示要打开的文件名。
- mode:可选参数,文件打开模式。这个参数是非强制的,默认文件访问模式为只读(r)。不同模式打开文件的完全列表如表1-1所示。
表1-1 不同模式打开文件的完全列表
模式 | 描述 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
- bufering:可选参数,缓冲区大小。
- encoding:文件编码类型。
- errors:编码错误处理方法。
- newline:控制通用换行符模式的行为。
- closefd:控制在关闭文件时是否彻底关闭文件。
当在Python程序中对文本文件进行读写操作时,有时可能会针对不同的文本编码进行操作,例如ASCII、UTF-8和UTF-16 编码。在读取文件内容时,可以使用open()函数并配合rt 模式来实现,例如下面的演示代码:
with open('somefile.txt', 'rt') as f:
data = f.read()
# Iterate over the lines of the file
with open('somefile.txt', 'rt') as f:
for line in f:
# process line
...
在默认情况下,文件的读取和写入操作采用的都是系统默认的文本编码方式,具体可以通过sys.getdefaultencoding()函数来查询。在大多数机器上,这项设定都被设置为utf-8。如果我们知道正在读取或写入的文本采用的是另外一种编码方式,那么可以为open()函数提供了一个可选的编码参数。虽然Python可以识别出上百种可能的文本编码,但是最为常用的编码方式不外乎是ASCII、utf-8和utf-16等。
函数open()中的file参数表示的需要打开文件的相对路径(当前工作目录)或者一个绝对路径,当传入路径不存在此文件会报错。例如下面的演示过程。
>>> a = open('test.txt') # 相对路径
>>> a
<_io.TextIOWrapper name='test.txt' mode='r' encoding='cp936'>
>>> a.close()
>>> a = open(r'D:\Python\Python35-32\test.txt') # 绝对路径
>>> a
<_io.TextIOWrapper name='D:\\Python\\Python35-32\\test.txt' mode='r' encoding='cp936'>
1.47 函数ord()
在Python程序中,使用函数ord()的语法格式如下所示。
ord(c)
参数c是一个字符,函数ord()的功能和chr()函数刚好相反,功能是返回参数c对应的整数数值。函数ord()以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值。例如,ord('a')返回整数97和ord('€')(欧元符号)返回8364。如果所给的 Unicode 字符超出了你的 Python 定义范围,则会引发一个 TypeError异常。
在下面的实例文件ord.py中,演示了使用函数ord()返回整数数值的过程。
print(ord('a'))
print(ord('@'))
print(chr(97))
print(chr(64))
执行后会输出:
97
64
a
@
1.48 函数pow()
在Python程序中,使用函数pow()的语法格式如下所示。
pow(x, y[, z])
函数pow()的功能是计算x的y次方值,如果参数z存在,则再对结果进行取模运算,其结果等效于pow(x,y) %z。函数pow()的参数必须是数字类型,由于操作数是混合类型的,二进制计算的原因需要一些强制的规定。对于int操作数,结果具有与操作数相同的类型(强制后),除非第二个参数为负;在这种情况下,所有参数都转换为float,并传递float结果。例如, 10**2 返回 100, 但 10**-2 返回0.01。如果第二个参数为负数,那么第三个参数必须省略。
在下面的实例文件pow.py中,演示了使用函数pow()计算指定数字指定次方值的过程。
import math # 导入 math 模块
print ("math.pow(100, 2) : ", math.pow(100, 2))#使用math 模块的pow()函数
# 使用内置,查看输出结果区别
print ("pow(100, 2) : ", pow(100, 2))
print ("math.pow(100, -2) : ", math.pow(100, -2))
print ("math.pow(2, 4) : ", math.pow(2, 4))
print ("math.pow(3, 0) : ", math.pow(3, 0))
执行后会输出:
math.pow(100, 2) : 10000.0
pow(100, 2) : 10000
math.pow(100, -2) : 0.0001
math.pow(2, 4) : 16.0
math.pow(3, 0) : 1.0
函数pow()的所有参数必须是数值类型,否则运行后会出错。例如下面的演示过程。
>>> pow('2',3)
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
pow('2',3)
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'
如果函数pow()的参数x和y有一个是浮点数,则结果将转换成浮点数。例如下面的演示过程。
>>> pow(2,0.1)
1.0717734625362931
如果函数pow()的参数x和y都是整数,则结果也是整数,除非y是负数;如果y是负数,则结果返回的是浮点数,浮点数不能取模,所有可选参数z不能传入值。例如下面的演示过程。
>>> pow(10,2)
100
>>> pow(10,-2)
0.01
>>> pow(10,-2,3)
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
pow(10,-2,3)
ValueError: pow() 2nd argument cannot be negative when 3rd argument specified
如果函数pow()的可选参数z传入了值,则x和y必须为整数,且y不能为负数。例如下面的演示过程。
>>> pow(2,3,5)
3
>>> pow(10,0.1,3)
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
pow(10,0.1,3)
TypeError: pow() 3rd argument not allowed unless all arguments are integers
>>> pow(10,-2,3)
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
pow(10,-2,3)
ValueError: pow() 2nd argument cannot be negative when 3rd argument specified
1.49 函数print()
在Python程序中,使用函数print()的语法格式如下所示。
print(*objects, sep=' ', end='\n', file=sys.stdout, ,flush=False)
- objects:复数,表示可以一次输出多个对象。当输出多个对象时,需要用逗号分隔;
- sep:用来间隔多个对象,默认值是一个空格;
- end:用来设定以什么结尾,默认值是换行符 \n,可以将其换成其他字符串;
- file:要写入的文件对象;
- flush:设置输出是否使用缓存,默认False。如果设置为ture,那么输出流将会被强制刷新。
函数print()的功能是实现打印输出功能,这是Python程序中最常见的一个函数。例如在下面的实例文件print.py中,演示了使用函数print()打印输出指定内容的过程。
print(1,2,3)
print(1,2,3,sep = '+')
print(1,2,3,sep = '+',end = '=?')
#sep、end、file、flush都必须以命名参数方式传参,否则将被当做需要输出的对象
print(1,2,3,'+','=?')
#不给print传递任何参数,将只输出end参数的默认值。
print()
print(end = 'by 2016')
# file参数必须是一个含有write(string) 方法的对象。
class A:
@staticmethod
def write(s):
print(s)
a = A()
print(1,2,3,sep = '+',end = '=?',file = a)
#sep和end参数必须是字符串;或者为None,为None时意味着将使用其默认值。
#print(1,2,3,sep = 97,end = 100)#这行会出错
print(1,2,3,sep = None,end = None)
执行后会输出:
1 2 3
1+2+3
1+2+3=?1 2 3 + =?
by 20161
+
2
+
3
=?
1 2 3
1.50 函数property()
在Python程序中,使用函数property()的语法格式如下所示。
class property([fget[, fset[, fdel[, doc]]]])
- fget:获取属性值的函数;
- fset:设置属性值的函数;
- fdel:删除属性值函数;
- doc:属性描述信息。
函数property()的功能是返回一个property 属性。property是一个类,其作用是用来包装类的属性,这个属性可以根据实际需要,控制是否可读(设置fget参数)、可写(设置fset参数)、可删除(设置fdel参数)。例如在下面的实例文件property.py中,演示了使用函数property()定义一个可控属性值 x的过程。
class C(object):
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
c = C()
print(c.x) # 调用 getx
c.x = 'x had changed' # 调用 setx
print(c.x) # 调用 getx
#参数doc表示的是属性的说明,如果没有指定,将从fget参数指定的方法中读取。
print(help(c))
del c.x # 调用 delx
#print(c.x) # 调用 getx会出错
class Parrot(object):
def __init__(self):
self._voltage = 100000
@property
def voltage(self):
"""Get the current voltage."""
return self._voltage
在上述代码中,如果c是C的实例化, 则c.x将会触发getter,c.x = value将会触发setter,del c.x会触发deleter。如果给定了参数doc,其将成为这个属性值的 docstring,否则property()函数会复制 fget()函数的docstring(如果有的话)。
在类Parrot中将property()函数用作装饰器可以很方便的创建只读属性,将voltage()方法转化成同名只读属性的getter方法。
执行后会输出:
None
x had changed
Help on C in module __main__ object:
class C(builtins.object)
| Methods defined here:
|
| __init__(self)
| Initialize self. See help(type(self)) for accurate signature.
|
| delx(self)
|
| getx(self)
|
| setx(self, value)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| x
| I'm the 'x' property.
None
函数property()中的getter、setter和deleter方法同样可以用作装饰器,例如下面的演示代码。
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
在上述代码中需要注意这些额外函数的名字和 property下的一样,例如上面的x。
函数property()中的参数doc表示的是属性的说明,如果没有指定,将从fget参数指定的方法中读取。例如下面的演示过程。
# 最后一行中 文档字符串 为I'm the 'x' property.
>>> class C:
def __init__(self):
self._x = '_x in C'
def getx(self):
"""I'm the 'x' property. provide by getx"""
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx)
>>> help(C)
Help on class C in module __main__:
class C(builtins.object)
| Methods defined here:
|
| __init__(self)
| Initialize self. See help(type(self)) for accurate signature.
|
| delx(self)
|
| getx(self)
| I'm the 'x' property. provide by getx
|
| setx(self, value)
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
|
| x
| I'm the 'x' property. provide by getx
# 最后一行中 文档字符串 为 I'm the 'x' property. provide by getx
在使用函数property()时,更优雅的做法是用作装饰器,装饰过的方法就可以以属性方式调用。同时将生成.setter和.deleter装饰器,用于指定可入方法和删除方法。例如下面的演示过程。
>>> class C:
def __init__(self):
self._x = '_x in C'
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
>>> c = C()
>>> c.x # 调用 getx
'_x in C'
>>> c.x = 'x had changed' # 调用 setx
>>> c.x # 调用 getx
'x had changed'
>>> del c.x # 调用 delx
>>> c.x # 调用 getx
Traceback (most recent call last):
File "<pyshell#34>", line 1, in <module>
c.x
File "<pyshell#28>", line 6, in getx
return self._x
AttributeError: 'C' object has no attribute '_x'
在使用函数property()时通常不直接使用字段,而是使用属性,这是因为可以控制外部对类字段的恶意修改和删除,而且可以再设置属性值的时候进行适当的验证。例如下面的演示过程。
>>> class C:
def __init__(self):
self._name = ''
@property
def name(self):
"""i'm the 'name' property."""
return self._name
@name.setter
def name(self,value):
if value is None:
raise RuntimeError('name can not be None')
else:
self._name = value
>>> c = C()
>>> c.name # 访问属性
''
>>> c.name = None # 设置属性时进行验证
Traceback (most recent call last):
File "<pyshell#84>", line 1, in <module>
c.name = None
File "<pyshell#81>", line 11, in name
raise RuntimeError('name can not be None')
RuntimeError: name can not be None
>>> c.name = 'Kim' # 设置属性
>>> c.name # 访问属性
'Kim'
>>> del c.name # 删除属性,不提供deleter则不能删除
Traceback (most recent call last):
File "<pyshell#87>", line 1, in <module>
del c.name
AttributeError: can't delete attribute
>>> c.name
'Kim'