python基础整理(2)

布尔表达式与其余值的替换

值的测试

Python不仅仅可以使用布尔型变量作为条件,它可以直接在if中使用任何表达式作为条件:

大部分表达式的值都会被当作True,但以下表达式值会被当作False

  • False
  • None
  • 0
  • 空字符串,空列表,空字典,空集合

循环

else语句

if 一样, whilefor 循环后面也可以跟着 else 语句,不过要和break一起连用。

  • 当循环正常结束时,循环条件不满足, else 被执行;
  • 当循环被 break 结束时,循环条件仍然满足, else 不执行。
values = [7, 6, 4, 7, 19, 2, 1]
for x in values:
    if x <= 10:
        print 'Found:', x
        break
else:
    print 'All values greater than 10'

xrange函数

total = 0
for i in range(100000):
    total += i
print total
4999950000

然而这种写法有一个缺点:在循环前,它会生成一个长度为 100000 的临时列表。

生成列表的问题在于,会有一定的时间和内存消耗,当数字从 100000 变得更大时,时间和内存的消耗会更加明显。

为了解决这个问题,我们可以使用 xrange 来代替 range 函数,其效果与range函数相同,但是 xrange 并不会一次性的产生所有的数据:

total = 0
for i in xrange(100000):
    total += i
print total
4999950000

列表推导式

values = [10, 21, 4, 7, 12]
squares = [x**2 for x in values]
print squares
[100, 441, 16, 49, 144]

还可以在列表推导式中加入条件进行筛选。 例如在上面的例子中,假如只想保留列表中不大于10的数的平方:

values = [10, 21, 4, 7, 12]
squares = [x**2 for x in values if x <= 10]
print squares
[100, 16, 49]

也可以使用推导式生成集合和字典

square_set = {x**2 for x in values if x <= 10}
print(square_set)
square_dict = {x: x**2 for x in values if x <= 10}
print(square_dict)

set([16, 49, 100])
{10: 100, 4: 16, 7: 49}

再如,计算上面例子中生成的列表中所有元素的和:

total = sum([x**2 for x in values if x <= 10])
print(total)
165

但是,Python会生成这个列表,然后在将它放到垃圾回收机制中(因为没有变量指向它),这毫无疑问是种浪费。

为了解决这种问题,与xrange()类似,Python使用产生式表达式来解决这个问题:

total = sum(x**2 for x in values if x <= 10)
print(total)
165

与上面相比,只是去掉了括号,但这里并不会一次性的生成这个列表。

函数

接收不定参数

def add(x, *args):
    total = x
    for arg in args:
        total += arg
    return total

这里,*args 表示参数数目不定,可以看成一个元组,把第一个参数后面的参数当作元组中的元素。

这样定义的函数不能使用关键词传入参数,要使用关键词,可以这样:

def add(x, **kwargs):
    total = x
    for arg, value in kwargs.items():
        print "adding ", arg
        total += value
    return total

这里, ** kwargs 表示参数数目不定,相当于一个字典,关键词和值对应于键值对。

print add(10, y=11, z=12, w=13)
adding  y
adding  z
adding  w
46

再看这个例子,可以接收任意数目的位置参数和键值对参数:

def foo(*args, **kwargs):
    print args, kwargs

foo(2, 3, x='bar', z=10)
(2, 3) {'x': 'bar', 'z': 10}

不过要按顺序传入参数,先传入位置参数 args ,在传入关键词参数 kwargs

返回多个值

函数可以返回多个值:

事实上,Python将返回的两个值变成了元组:

print to_polar(3, 4)
(5.0, 0.9272952180016122)

因为这个元组中有两个值,所以可以给两个值赋值。

列表也有相似的功能:

a, b, c = [1, 2, 3]
print a, b, c
1 2 3

事实上,不仅仅返回值可以用元组表示,也可以将参数用元组以这种方式传入:

def add(x, y):
    """Add two numbers"""
    a = x + y
    return a
    
z = (2, 3)
print add(*z)
5

这里的*必不可少。

还可以通过字典传入参数来执行函数:

def add(x, y):
    """Add two numbers"""
    a = x + y
    return a

w = {'x': 2, 'y': 3}
print add(**w)
5

map 方法生成序列

可以通过 map 的方式利用函数来生成序列:

def sqr(x): 
    return x ** 2

a = [2,3,4]
print map(sqr, a)
[4, 9, 16]

其用法为:

map(aFun, aSeq)

将函数 aFun 应用到序列 aSeq 上的每一个元素上,返回一个列表,不管这个序列原来是什么类型。

事实上,根据函数参数的多少,map 可以接受多组序列,将其对应的元素作为参数传入函数:

def add(x, y): 
    return x + y

a = (2,3,4)
b = [10,5,3]
print map(add,a,b)
[12, 8, 7]

模块和包

在导入时,Python会执行一遍模块中的所有内容。

ex1.py 中所有的变量都被载入了当前环境中,不过要使用

ex1.变量名  的方法来查看或者修改这些变量
ex1.函数名  调用模块里面的函数:

为了提高效率,Python只会载入模块一次,已经载入的模块再次载入时,Python并不会真正执行载入操作,哪怕模块的内容已经改变。 需要重新导入模块时,可以使用reload强制重新载入它

_name__ 属性

有时候我们想将一个 .py 文件既当作脚本,又能当作模块用,这个时候可以使用 __name__ 这个属性。

只有当文件被当作脚本执行的时候, __name__的值才会是 '__main__',所以我们可以:

%%writefile ex2.y

PI = 3.1416

def test():
    w = [0,1,2,3]
    print 'test passed.'
    
if __name__ == '__main__':
    test()

假设我们有这样的一个文件夹:

foo/

  • __init__.py
  • bar.py (defines func)
  • baz.py (defines zap)

这意味着 foo 是一个包,我们可以这样导入其中的内容:

from foo.bar import func
from foo.baz import zap

barbaz 都是 foo 文件夹下的 .py 文件。

导入包要求:

  • 文件夹 fooPython的搜索路径中
  • __init__.py 表示 foo 是一个包,它可以是个空文件。

异常

try & except 块

一旦 try 块中的内容出现了异常,那么 try 块后面的内容会被忽略,Python会寻找 except 里面有没有对应的内容,如果找到,就执行对应的块,没有则抛出这个异常。

如:try 抛出的是 ValueErrorexcept 中有对应的内容,所以这个异常被 except 捕捉到,程序可以继续执行

finally

try/catch 块还有一个可选的关键词 finally。

不管 try 块有没有异常, finally 块的内容总是会被执行,而且会在抛出异常前执行,因此可以用来作为安全保证,比如确保打开的文件被关闭

在抛出异常前执行, 如果异常被捕获了,在最后执行。

文件读写

写入测试文件:

%%writefile test.txt
this is a test fileS.
hello world!
python is good!
today is a good day.

Writing test.txt

读文件

使用 open 函数或者 file 函数来读文件,使用文件名的字符串作为输入参数:这两种方式没有太大区别。

f = open('test.txt')

f = file('test.txt')

默认以读的方式打开文件,如果文件不存在会报错。

可以使用 read 方法来读入文件中的所有内容:

text = f.read()
print text

this is a test file.
hello world!
python is good!
today is a good day.

也可以按照行读入内容readlines 方法返回一个列表,每个元素代表文件中每一行的内容:

f = open('test.txt')
lines = f.readlines()
print lines

['this is a test file.\n', 'hello world!\n', 'python is good!\n', 'today is a good day.']

使用完文件之后,需要将文件关闭。

f.close()

事实上,我们可以将 f 放在一个循环中,得到它每一行的内容:

写文件

我们使用 open 函数的写入模式来写文件:

f = open('myfile.txt', 'w')
f.write('hello world!')
f.close()

使用 w 模式时,如果文件不存在会被创建,我们可以查看是否真的写入成功:

如果文件已经存在, w 模式会覆盖之前写的所有内容:

除了写入模式,还有追加模式 a ,追加模式不会覆盖之前已经写入的内容,而是在之后继续写入:

写入结束之后一定要将文件关闭,否则可能出现内容没有完全写入文件中的情况。

还可以使用读写模式 w+

f = open('myfile.txt', 'w+')
f.write('hello world!')
f.seek(6)
print f.read()
f.close()
world!

二进制文件

二进制读写模式 b:

import os
f = open('binary.bin', 'wb')
f.write(os.urandom(16))
f.close()

f = open('binary.bin', 'rb')
print repr(f.read())
f.close()
'\x86H\x93\xe1\xd8\xef\xc0\xaa(\x17\xa9\xc9\xa51\xf1\x98'

换行符

不同操作系统的换行符可能不同:

  • \r
  • \n
  • \r\n

使用 U 选项,可以将这三个统一看成 \n 换行符。

关闭文件

Python中,如果一个打开的文件不再被其他变量引用时,它会自动关闭这个文件。

所以正常情况下,如果一个文件正常被关闭了,忘记调用文件的 close 方法不会有什么问题。

关闭文件可以保证内容已经被写入文件,而不关闭可能会出现意想不到的结果:

with 方法

Python提供了更安全的方法,当 with 块的内容结束后,Python会自动调用它的close 方法,确保读写的安全:

with open('newfile.txt','w') as f:
    for i in range(3000):
        x = 1.0 / (i - 1000)
        f.write('hello world: ' + str(i) + '\n')
        
        
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-24-9d2a70065b27> in <module>()
      1 with open('newfile.txt','w') as f:
      2     for i in range(3000):
----> 3         x = 1.0 / (i - 1000)
      4         f.write('hello world: ' + str(i) + '\n')

ZeroDivisionError: float division by zero

try/exception/finally 效果相同,但更简单。

猜你喜欢

转载自www.cnblogs.com/dingruihfut/p/11728742.html