python3学习笔记(二)

一、Python3 编程第一步

在前面的教程中咱们已经学习了一些 Python3 的基本语法知识,下面咱们尝试来写一个斐波纳契数列。html

实例(Python 3.0+)python

# Fibonacci series: 斐波纳契数列
# 两个元素的总和肯定了下一个数
a, b = 0, 1
while b < 10:
    print(b)
    a, b = b, a+b复制代码

其中代码 a, b = b, a+b 的计算方式为先计算右边表达式,而后同时赋值给左边,等价于:linux

n=b
m=a+b
a=n
b=m复制代码

执行以上程序,输出结果为:c++

1
1
2
3
5
8复制代码

这个例子介绍了几个新特征。程序员

第一行包含了一个复合赋值:变量 a 和 b 同时获得新值 0 和 1。最后一行再次使用了一样的方法,能够看到,右边的表达式会在赋值变更以前执行。右边表达式的执行顺序是从左往右的。express

输出变量值:编程

>>> i = 256*256
>>> print('i 的值为:', i)
i 的值为: 65536复制代码

1. end 关键字

关键字end能够用于将结果输出到同一行,或者在输出的末尾添加不一样的字符,实例以下:api

实例(Python 3.0+)bash

# Fibonacci series: 斐波纳契数列
# 两个元素的总和肯定了下一个数
a, b = 0, 1
while b < 1000:
    print(b, end=',')
    a, b = b, a+b复制代码

执行以上程序,输出结果为:服务器

1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,复制代码

二、Python3 条件控制

Python 条件语句是经过一条或多条语句的执行结果(True 或者 False)来决定执行的代码块。

1. if 语句

Python中if语句的通常形式以下所示:

if condition_1: statement_block_1 elif condition_2: statement_block_2 else: statement_block_3
  • 若是 "condition_1" 为 True 将执行 "statement_block_1" 块语句
  • 若是 "condition_1" 为False,将判断 "condition_2"
  • 若是"condition_2" 为 True 将执行 "statement_block_2" 块语句
  • 若是 "condition_2" 为False,将执行"statement_block_3"块语句

Python 中用 elif 代替了 else if,因此if语句的关键字为:if – elif – else

注意:

  • 一、每一个条件后面要使用冒号 :,表示接下来是知足条件后要执行的语句块。
  • 二、使用缩进来划分语句块,相同缩进数的语句在一块儿组成一个语句块。
  • 三、在Python中没有switch – case语句。

实例

var1 = 100
if var1:
    print ("1 - if 表达式条件为 true")
    print (var1)
 
var2 = 0
if var2:
    print ("2 - if 表达式条件为 true")
    print (var2)
print ("Good bye!")复制代码

执行以上代码,输出结果为:

1 - if 表达式条件为 true
100
Good bye!
复制代码

从结果能够看到因为变量 var2 为 0,因此对应的 if 内的语句没有执行。

如下实例演示了狗的年龄计算判断:

实例

age = int(input("请输入你家狗狗的年龄: "))
print("")
if age <= 0:
    print("你是在逗我吧!")
elif age == 1:
    print("至关于 14 岁的人。")
elif age == 2:
    print("至关于 22 岁的人。")
elif age > 2:
    human = 22 + (age -2)*5
    print("对应人类年龄: ", human)
 
### 退出提示
input("点击 enter 键退出")复制代码

将以上脚本保存在dog.py文件中,并执行该脚本:

$ python3 dog.py 
请输入你家狗狗的年龄: 1

至关于 14 岁的人。
点击 enter 键退出
复制代码

如下为if中经常使用的操做运算符:

操做符 描述
< 小于
<= 小于或等于
> 大于
>= 大于或等于
== 等于,比较两个值是否相等
!= 不等于

实例

# 程序演示了 == 操做符
# 使用数字
print(5 == 6)
# 使用变量
x = 5
y = 8
print(x == y)复制代码

以上实例输出结果:

False
False
复制代码

high_low.py文件演示了数字的比较运算:

实例

# 该实例演示了数字猜谜游戏
number = 7
guess = -1
print("数字猜谜游戏!")
while guess != number:
    guess = int(input("请输入你猜的数字:"))
 
    if guess == number:
        print("恭喜,你猜对了!")
    elif guess < number:
        print("猜的数字小了...")
    elif guess > number:
        print("猜的数字大了...")复制代码

执行以上脚本,实例输出结果以下:

$ python3 high_low.py 
数字猜谜游戏!
请输入你猜的数字:1
猜的数字小了...
请输入你猜的数字:9
猜的数字大了...
请输入你猜的数字:7
恭喜,你猜对了!
复制代码

2. if 嵌套

在嵌套 if 语句中,能够把 if...elif...else 结构放在另一个 if...elif...else 结构中。

if 表达式1:
    语句
    if 表达式2:
        语句
    elif 表达式3:
        语句
    else:
        语句
elif 表达式4:
    语句
else:
    语句
复制代码

实例

num=int(input("输入一个数字:"))
if num%2==0:
    if num%3==0:
        print ("你输入的数字能够整除 2 和 3")
    else:
        print ("你输入的数字能够整除 2,但不能整除 3")
else:
    if num%3==0:
        print ("你输入的数字能够整除 3,但不能整除 2")
    else:
        print  ("你输入的数字不能整除 2 和 3")复制代码

将以上程序保存到 test_if.py 文件中,执行后输出结果为:

$ python3 test.py 
输入一个数字:6
你输入的数字能够整除 2 和 3复制代码

三、Python3 循环语句

本章节将为你们介绍 Python 循环语句的使用。

Python 中的循环语句有 for 和 while。

1. while 循环

Python 中 while 语句的通常形式:

while 判断条件(condition):
    执行语句(statements)……复制代码

一样须要注意冒号和缩进。另外,在 Python 中没有 do..while 循环。

如下实例使用了 while 来计算 1 到 100 的总和:

实例

n = 100
 
sum = 0
counter = 1
while counter <= n:
    sum = sum + counter
    counter += 1
 
print("1 到 %d 之和为: %d" % (n,sum))复制代码

执行结果以下:

1 到 100 之和为: 5050复制代码

无限循环

咱们能够经过设置条件表达式永远不为 false 来实现无限循环,实例以下:

实例

var = 1
while var == 1 :  # 表达式永远为 true
   num = int(input("输入一个数字 :"))
   print ("你输入的数字是: ", num)
 
print ("Good bye!")复制代码

执行以上脚本,输出结果以下:

输入一个数字  :5
你输入的数字是:  5
输入一个数字  :复制代码

你可使用 CTRL+C 来退出当前的无限循环。

无限循环在服务器上客户端的实时请求很是有用。

2. while 循环使用 else 语句

在 while … else 在条件语句为 false 时执行 else 的语句块。

语法格式以下:

while <expr>:
    <statement(s)>
else:
    <additional_statement(s)>复制代码

循环输出数字,并判断大小:

实例

count = 0
while count < 5:
   print (count, " 小于 5")
   count = count + 1
else:
   print (count, " 大于或等于 5")复制代码

执行以上脚本,输出结果以下:

0  小于 5
1  小于 5
2  小于 5
3  小于 5
4  小于 5
5  大于或等于 5复制代码

简单语句组

相似if语句的语法,若是你的while循环体中只有一条语句,你能够将该语句与while写在同一行中, 以下所示:

实例

flag = 1
 
while (flag): print ('欢迎访问菜鸟教程!')
 
print ("Good bye!")复制代码

注意:以上的无限循环你可使用 CTRL+C 来中断循环。

执行以上脚本,输出结果以下:

欢迎访问菜鸟教程!
欢迎访问菜鸟教程!
欢迎访问菜鸟教程!
欢迎访问菜鸟教程!
欢迎访问菜鸟教程!
……复制代码

2. for 语句

Python for循环能够遍历任何序列的项目,如一个列表或者一个字符串。

for循环的通常格式以下:

for <variable> in <sequence>:
    <statements>
else:
    <statements>复制代码

Python for 循环实例:

实例

>>>languages = ["C", "C++", "Perl", "Python"] 
>>> for x in languages:
...     print (x)
... 
C
C++
Perl
Python
>>>复制代码

如下 for 实例中使用了 break 语句,break 语句用于跳出当前循环体:

实例

sites = ["Baidu", "Google","Runoob","Taobao"]
for site in sites:
    if site == "Runoob":
        print("菜鸟教程!")
        break
    print("循环数据 " + site)
else:
    print("没有循环数据!")
print("完成循环!")复制代码

执行脚本后,在循环到 "Runoob"时会跳出循环体:

循环数据 Baidu
循环数据 Google
菜鸟教程!
完成循环!复制代码

4. range()函数

若是你须要遍历数字序列,可使用内置range()函数。它会生成数列,例如:

实例

>>>for i in range(5):
...     print(i)
...
0
1
2
3
4复制代码

你也可使用range指定区间的值:

实例

>>>for i in range(5,9) :
    print(i)
 
    
5
6
7
8
>>>复制代码

也可使range以指定数字开始并指定不一样的增量(甚至能够是负数,有时这也叫作'步长'):

实例

>>>for i in range(0, 10, 3) :
    print(i)
 
    
0
3
6
9
>>>复制代码

负数:

实例

>>>for i in range(-10, -100, -30) :
    print(i)
 
    
-10
-40
-70
>>>复制代码

您能够结合range()和len()函数以遍历一个序列的索引,以下所示:

实例

>>>a = ['Google', 'Baidu', 'Runoob', 'Taobao', 'QQ']
>>> for i in range(len(a)):
...     print(i, a[i])
... 
0 Google
1 Baidu
2 Runoob
3 Taobao
4 QQ
>>>复制代码

还可使用range()函数来建立一个列表:

实例

>>>list(range(5))
[0, 1, 2, 3, 4]
>>>复制代码

5. break 和 continue 语句及循环中的 else 子句

break 执行流程图:

continue 执行流程图:

代码执行过程:

break 语句能够跳出 for 和 while 的循环体。若是你从 for 或 while 循环中终止,任何对应的循环 else 块将不执行。

continue 语句被用来告诉 Python 跳过当前循环块中的剩余语句,而后继续进行下一轮循环。

实例

while 中使用 break:

实例

n = 5
while n > 0:    
    n -= 1    
    if n == 2:        
        break    
    print(n)
print('循环结束。')复制代码

输出结果为:

4
3
循环结束。复制代码

while 中使用 continue:

实例

n = 5
while n > 0:    
    n -= 1    
    if n == 2:        
        continue    
    print(n)
print('循环结束。')复制代码

输出结果为:

4
3
1
0
循环结束。复制代码

更多实例以下:

实例

for letter in 'Runoob':     # 第一个实例
   if letter == 'b':
      break
   print ('当前字母为 :', letter)
  
var = 10                    # 第二个实例
while var > 0:              
   print ('当期变量值为 :', var)
   var = var -1
   if var == 5:
      break
 
print ("Good bye!")复制代码

执行以上脚本输出结果为:

当前字母为 : R
当前字母为 : u
当前字母为 : n
当前字母为 : o
当前字母为 : o
当期变量值为 : 10
当期变量值为 : 9
当期变量值为 : 8
当期变量值为 : 7
当期变量值为 : 6
Good bye!复制代码

如下实例循环字符串 Runoob,碰到字母 o 跳过输出:

实例

for letter in 'Runoob':     # 第一个实例
   if letter == 'o':        # 字母为 o 时跳过输出
      continue
   print ('当前字母 :', letter)
 
var = 10                    # 第二个实例
while var > 0:              
   var = var -1
   if var == 5:             # 变量为 5 时跳过输出
      continue
   print ('当前变量值 :', var)
print ("Good bye!")复制代码

执行以上脚本输出结果为:

当前字母 : R
当前字母 : u
当前字母 : n
当前字母 : b
当前变量值 : 9
当前变量值 : 8
当前变量值 : 7
当前变量值 : 6
当前变量值 : 4
当前变量值 : 3
当前变量值 : 2
当前变量值 : 1
当前变量值 : 0
Good bye!复制代码

循环语句能够有 else 子句,它在穷尽列表(以for循环)或条件变为 false (以while循环)致使循环终止时被执行,但循环被 break 终止时不执行。

以下实例用于查询质数的循环例子:

实例

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(n, '等于', x, '*', n//x)
            break
    else:
        # 循环中没有找到元素
        print(n, ' 是质数')复制代码

执行以上脚本输出结果为:

2  是质数
3  是质数
4 等于 2 * 2
5  是质数
6 等于 2 * 3
7  是质数
8 等于 2 * 4
9 等于 3 * 3复制代码

6. pass 语句

Python pass是空语句,是为了保持程序结构的完整性。

pass 不作任何事情,通常用作占位语句,以下实例

实例

>>>while True:
...     pass  # 等待键盘中断 (Ctrl+C)复制代码

最小的类:

实例

>>>class MyEmptyClass:
...     pass复制代码

如下实例在字母为 o 时 执行 pass 语句块:

实例

for letter in 'Runoob': 
   if letter == 'o':
      pass
      print ('执行 pass 块')
   print ('当前字母 :', letter)
 
print ("Good bye!")复制代码

执行以上脚本输出结果为:

当前字母 : R
当前字母 : u
当前字母 : n
执行 pass 块
当前字母 : o
执行 pass 块
当前字母 : o
当前字母 : b
Good bye!复制代码

四、Python3 迭代器与生成器

1. 迭代器

迭代是Python最强大的功能之一,是访问集合元素的一种方式。

迭代器是一个能够记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到全部的元素被访问完结束。迭代器只能往前不会后退。

迭代器有两个基本的方法:iter()next()

字符串,列表或元组对象均可用于建立迭代器:

实例(Python 3.0+)

>>> list=[1,2,3,4]
>>> it = iter(list)    # 建立迭代器对象
>>> print (next(it))   # 输出迭代器的下一个元素
1
>>> print (next(it))
2
>>>复制代码

迭代器对象可使用常规for语句进行遍历:

实例(Python 3.0+)

list=[1,2,3,4]
it = iter(list)    # 建立迭代器对象
for x in it:
    print (x, end=" ")复制代码

执行以上程序,输出结果以下:

1 2 3 4复制代码

也可使用 next() 函数:

实例(Python 3.0+)

import sys         # 引入 sys 模块
 
list=[1,2,3,4]
it = iter(list)    # 建立迭代器对象
 
while True:
    try:
        print (next(it))
    except StopIteration:
        sys.exit()复制代码

执行以上程序,输出结果以下:

1
2
3
4复制代码

2. 建立一个迭代器

把一个类做为一个迭代器使用须要在类中实现两个方法 __iter__() 与 __next__() 。

若是你已经了解的面向对象编程,就知道类都有一个构造函数,Python 的构造函数为 __init__(), 它会在对象初始化的时候执行。

更多内容查阅:Python3 面向对象

__iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并经过 StopIteration 异常标识迭代的完成。

__next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。

建立一个返回数字的迭代器,初始值为 1,逐步递增 1:

实例(Python 3.0+)

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    x = self.a
    self.a += 1
    return x
 
myclass = MyNumbers()
myiter = iter(myclass)
 
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))复制代码

执行输出结果为:

1
2
3
4
5复制代码

3. StopIteration

StopIteration 异经常使用于标识迭代的完成,防止出现无限循环的状况,在 __next__() 方法中咱们能够设置在完成指定循环次数后触发 StopIteration 异常来结束迭代。

在 20 次迭代后中止执行:

实例(Python 3.0+)

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    if self.a <= 20:
      x = self.a
      self.a += 1
      return x
    else:
      raise StopIteration
 
myclass = MyNumbers()
myiter = iter(myclass)
 
for x in myiter:
  print(x)复制代码

执行输出结果为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20复制代码

4. 生成器

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

跟普通函数不一样的是,生成器是一个返回迭代器的函数,只能用于迭代操做,更简单点理解生成器就是一个迭代器。

在调用生成器运行的过程当中,每次遇到 yield 时函数会暂停并保存当前全部的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

调用一个生成器函数,返回的是一个迭代器对象。

如下实例使用 yield 实现斐波那契数列:

实例(Python 3.0+)

import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()复制代码

执行以上程序,输出结果以下:

0 1 1 2 3 5 8 13 21 34 55复制代码

五、Python3 函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提升应用的模块性,和代码的重复利用率。你已经知道Python提供了许多内建函数,好比print()。但你也能够本身建立函数,这被叫作用户自定义函数。

1. 定义一个函数

你能够定义一个由本身想要功能的函数,如下是简单的规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间能够用于定义参数。
  • 函数的第一行语句能够选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号起始,而且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return至关于返回 None。

语法

Python 定义函数使用 def 关键字,通常格式以下:

def 函数名(参数列表):
    函数体复制代码

默认状况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。

实例

让咱们使用函数来输出"Hello World!":

>>>def hello() :
   print("Hello World!")
 
   
>>> hello()
Hello World!
>>>复制代码

更复杂点的应用,函数中带上参数变量:

实例(Python 3.0+)

# 计算面积函数
def area(width, height):
    return width * height
 
def print_welcome(name):
    print("Welcome", name)
 
print_welcome("Runoob")
w = 4
h = 5
print("width =", w, " height =", h, " area =", area(w, h))复制代码

以上实例输出结果:

Welcome Runoob
width = 4  height = 5  area = 20复制代码

2. 函数调用

定义一个函数:给了函数一个名称,指定了函数里包含的参数,和代码块结构。

这个函数的基本结构完成之后,你能够经过另外一个函数调用执行,也能够直接从 Python 命令提示符执行。

以下实例调用了 printme() 函数:

实例(Python 3.0+)

# 定义函数
def printme( str ):
   # 打印任何传入的字符串
   print (str)
   return
 
# 调用函数
printme("我要调用用户自定义函数!")
printme("再次调用同一函数")复制代码

以上实例输出结果:

我要调用用户自定义函数!
再次调用同一函数复制代码

3. 参数传递

在 python 中,类型属于对象,变量是没有类型的:

a=[1,2,3]

a="Runoob"复制代码

以上代码中,[1,2,3] 是 List 类型,"Runoob" 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),能够是指向 List 类型对象,也能够是指向 String 类型对象。

可更改(mutable)与不可更改(immutable)对象

在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是能够修改的对象。

  • 不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,至关于新生成了a。

  • 可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,自己la没有动,只是其内部的一部分值被修改了。

python 函数的参数传递:

  • 不可变类型:相似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象自己。好比在 fun(a)内部修改 a 的值,只是修改另外一个复制的对象,不会影响 a 自己。

  • 可变类型:相似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响

python 中一切都是对象,严格意义咱们不能说值传递仍是引用传递,咱们应该说传不可变对象和传可变对象。

python 传不可变对象实例

实例(Python 3.0+)

def ChangeInt( a ):
    a = 10
 
b = 2
ChangeInt(b)
print( b ) 
# 结果是 2实例中有 int 对象 2,指向它的变量是 b,在传递给 ChangeInt 函数时,
#按传值的方式复制了变量 b,a 和 b 都指向了同一个 Int 对象,在 a=10 时,则新生
#成一个 int 值对象 10,并让 a 指向它。复制代码

传可变对象实例

可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。例如:

实例(Python 3.0+)

# 可写函数说明
def changeme( mylist ):
   "修改传入的列表"
   mylist.append([1,2,3,4])
   print ("函数内取值: ", mylist)
   return
 
# 调用changeme函数
mylist = [10,20,30]
changeme( mylist )
print ("函数外取值: ", mylist)复制代码

传入函数的和在末尾添加新内容的对象用的是同一个引用。故输出结果以下:

函数内取值:  [10, 20, 30, [1, 2, 3, 4]]
函数外取值:  [10, 20, 30, [1, 2, 3, 4]]复制代码

4. 参数

如下是调用函数时可以使用的正式参数类型:

  • 必需参数
  • 关键字参数
  • 默认参数
  • 不定长参数

必需参数

必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的同样。

调用 printme() 函数,你必须传入一个参数,否则会出现语法错误:

实例(Python 3.0+)

#可写函数说明
def printme( str ):
   "打印任何传入的字符串"
   print (str)
   return
 
# 调用 printme 函数,不加参数会报错
printme()复制代码

以上实例输出结果:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
    printme()
TypeError: printme() missing 1 required positional argument: 'str'复制代码

关键字参数

关键字参数和函数调用关系紧密,函数调用使用关键字参数来肯定传入的参数值。

使用关键字参数容许函数调用时参数的顺序与声明时不一致,由于 Python 解释器可以用参数名匹配参数值。

如下实例在函数 printme() 调用时使用参数名:

实例(Python 3.0+)

#可写函数说明
def printme( str ):
   "打印任何传入的字符串"
   print (str)
   return
 
#调用printme函数
printme( str = "菜鸟教程")复制代码

以上实例输出结果:

菜鸟教程复制代码

如下实例中演示了函数参数的使用不须要使用指定顺序:

实例(Python 3.0+)

#可写函数说明
def printinfo( name, age ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数
printinfo( age=50, name="runoob" )复制代码

以上实例输出结果:

名字:  runoob
年龄:  50复制代码

默认参数

调用函数时,若是没有传递参数,则会使用默认参数。如下实例中若是没有传入 age 参数,则使用默认值:

实例(Python 3.0+)

#可写函数说明
def printinfo( name, age = 35 ):
   "打印任何传入的字符串"
   print ("名字: ", name)
   print ("年龄: ", age)
   return
 
#调用printinfo函数
printinfo( age=50, name="runoob" )
print ("------------------------")
printinfo( name="runoob" )复制代码

以上实例输出结果:

名字:  runoob
年龄:  50
------------------------
名字:  runoob
年龄:  35复制代码

不定长参数

你可能须要一个函数能处理比当初声明时更多的参数。这些参数叫作不定长参数,和上述 2 种参数不一样,声明时不会命名。基本语法以下:

def functionname([formal_args,] *var_args_tuple ):
   "函数_文档字符串"
   function_suite
   return [expression]复制代码

加了星号 * 的参数会以元组(tuple)的形式导入,存放全部未命名的变量参数。

实例(Python 3.0+)

# 可写函数说明
def printinfo( arg1, *vartuple ):
   "打印任何传入的参数"
   print ("输出: ")
   print (arg1)
   print (vartuple)
 
# 调用printinfo 函数
printinfo( 70, 60, 50) 复制代码

以上实例输出结果:

输出: 
70
(60, 50)复制代码

若是在函数调用时没有指定参数,它就是一个空元组。咱们也能够不向函数传递未命名的变量。以下实例:

实例(Python 3.0+)

#!/usr/bin/python3
 
# 可写函数说明
def printinfo( arg1, *vartuple ):
   "打印任何传入的参数"
   print ("输出: ")
   print (arg1)
   for var in vartuple:
      print (var)
   return
 
# 调用printinfo 函数
printinfo( 10 )
printinfo( 70, 60, 50 )复制代码

以上实例输出结果:

输出:
10
输出:
70
60
50复制代码

还有一种就是参数带两个星号 **基本语法以下:

def functionname([formal_args,] **var_args_dict ):
   "函数_文档字符串"
   function_suite
   return [expression]复制代码

加了两个星号 ** 的参数会以字典的形式导入。

实例(Python 3.0+)

# 可写函数说明
def printinfo( arg1, **vardict ):
   "打印任何传入的参数"
   print ("输出: ")
   print (arg1)
   print (vardict)
 
# 调用printinfo 函数
printinfo(1, a=2,b=3)复制代码

以上实例输出结果:

输出: 
1
{'a': 2, 'b': 3}复制代码

声明函数时,参数中星号 * 能够单独出现,例如:

def f(a,b,*,c):
    return a+b+c复制代码

若是单独出现星号 * 后的参数必须用关键字传入。

>>> def f(a,b,*,c):
...     return a+b+c
... 
>>> f(1,2,3)   # 报错
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1,2,c=3) # 正常
6
>>>复制代码

5. 匿名函数

python 使用 lambda 来建立匿名函数。

所谓匿名,意即再也不使用 def 语句这样标准的形式定义一个函数。

  • lambda 只是一个表达式,函数体比 def 简单不少。
  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
  • lambda 函数拥有本身的命名空间,且不能访问本身参数列表以外或全局命名空间里的参数。
  • 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增长运行效率。

语法

lambda 函数的语法只包含一个语句,以下:

lambda [arg1 [,arg2,.....argn]]:expression复制代码

以下实例:

实例(Python 3.0+)

# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2
 
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))复制代码

以上实例输出结果:

相加后的值为 :  30
相加后的值为 :  40复制代码

6. return语句

return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的return语句返回None。以前的例子都没有示范如何返回数值,如下实例演示了 return 语句的用法:

实例(Python 3.0+)

# 可写函数说明
def sum( arg1, arg2 ):
   # 返回2个参数的和."
   total = arg1 + arg2
   print ("函数内 : ", total)
   return total
 
# 调用sum函数
total = sum( 10, 20 )
print ("函数外 : ", total)复制代码

以上实例输出结果:

函数内 :  30
函数外 :  30复制代码

7. 强制位置参数

Python3.8 新增了一个函数形参语法 / 用来指明函数形参必须使用指定位置参数,不能使用关键字参数的形式。

在如下的例子中,形参 a 和 b 必须使用指定位置参数,c 或 d 能够是位置形参或关键字形参,而 e 或 f 要求为关键字形参:

def f(a, b, /, c, d, *, e, f):
    print(a, b, c, d, e, f)复制代码

如下使用方法是正确的:

f(10, 20, 30, d=40, e=50, f=60)复制代码

如下使用方法会发生错误:

f(10, b=20, c=30, d=40, e=50, f=60)   # b 不能使用关键字参数的形式
f(10, 20, 30, 40, 50, f=60)           # e 必须使用关键字参数的形式复制代码

六、Python3 数据结构

本章节咱们主要结合前面所学的知识点来介绍Python数据结构。

1. 列表

Python中列表是可变的,这是它区别于字符串和元组的最重要的特色,一句话归纳即:列表能够修改,而字符串和元组不能。

如下是 Python 中列表的方法:

方法 描述
list.append(x) 把一个元素添加到列表的结尾,至关于 a[len(a):] = [x]。
list.extend(L) 经过添加指定列表的全部元素来扩充列表,至关于 a[len(a):] = L。
list.insert(i, x) 在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引,例如 a.insert(0, x) 会插入到整个列表以前,而 a.insert(len(a), x) 至关于 a.append(x) 。
list.remove(x) 删除列表中值为 x 的第一个元素。若是没有这样的元素,就会返回一个错误。
list.pop([i]) 从列表的指定位置移除元素,并将其返回。若是没有指定索引,a.pop()返回最后一个元素。元素随即从列表中被移除。(方法中 i 两边的方括号表示这个参数是可选的,而不是要求你输入一对方括号,你会常常在 Python 库参考手册中遇到这样的标记。)
list.clear() 移除列表中的全部项,等于del a[:]。
list.index(x) 返回列表中第一个值为 x 的元素的索引。若是没有匹配的元素就会返回一个错误。
list.count(x) 返回 x 在列表中出现的次数。
list.sort() 对列表中的元素进行排序。
list.reverse() 倒排列表中的元素。
list.copy() 返回列表的浅复制,等于a[:]。

下面示例演示了列表的大部分方法:

实例

>>> a = [66.25, 333, 333, 1, 1234.5]
>>> print(a.count(333), a.count(66.25), a.count('x'))
2 1 0
>>> a.insert(2, -1)
>>> a.append(333)
>>> a
[66.25, 333, -1, 333, 1, 1234.5, 333]
>>> a.index(333)
1
>>> a.remove(333)
>>> a
[66.25, -1, 333, 1, 1234.5, 333]
>>> a.reverse()
>>> a
[333, 1234.5, 1, 333, -1, 66.25]
>>> a.sort()
>>> a
[-1, 1, 66.25, 333, 333, 1234.5]复制代码

注意:相似 insert, remove 或 sort 等修改列表的方法没有返回值。

2. 将列表当作堆栈使用

列表方法使得列表能够很方便的做为一个堆栈来使用,堆栈做为特定的数据结构,最早进入的元素最后一个被释放(后进先出)。用 append() 方法能够把一个元素添加到堆栈顶。用不指定索引的 pop() 方法能够把一个元素从堆栈顶释放出来。例如:

实例

>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]复制代码

3. 将列表看成队列使用

也能够把列表当作队列用,只是在队列里第一加入的元素,第一个取出来;可是拿列表用做这样的目的效率不高。在列表的最后添加或者弹出元素速度快,然而在列表里插入或者从头部弹出速度却不快(由于全部其余的元素都得一个一个地移动)。

实例

>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry")           # Terry arrives
>>> queue.append("Graham")          # Graham arrives
>>> queue.popleft()                 # The first to arrive now leaves'Eric'
>>> queue.popleft()                 # The second to arrive now leaves'John'
>>> queue                           # Remaining queue in order of arrivaldeque(['Michael', 'Terry', 'Graham'])复制代码

4. 列表推导式

列表推导式提供了从序列建立列表的简单途径。一般应用程序将一些操做应用于某个序列的每一个元素,用其得到的结果做为生成新列表的元素,或者根据肯定的断定条件建立子序列。

每一个列表推导式都在 for 以后跟一个表达式,而后有零到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。若是但愿表达式推导出一个元组,就必须使用括号。

这里咱们将列表中每一个数值乘三,得到一个新的列表:

>>> vec = [2, 4, 6]
>>> [3*x for x in vec]
[6, 12, 18]复制代码

如今咱们玩一点小花样:

>>> [[x, x**2] for x in vec]
[[2, 4], [4, 16], [6, 36]]复制代码

这里咱们对序列里每个元素逐个调用某方法:

实例

>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']复制代码

咱们能够用 if 子句做为过滤器:

>>> [3*x for x in vec if x > 3]
[12, 18]
>>> [3*x for x in vec if x < 2]
[]复制代码

如下是一些关于循环和其它技巧的演示:

>>> vec1 = [2, 4, 6]
>>> vec2 = [4, 3, -9]
>>> [x*y for x in vec1 for y in vec2]
[8, 6, -18, 16, 12, -36, 24, 18, -54]
>>> [x+y for x in vec1 for y in vec2]
[6, 5, -7, 8, 7, -5, 10, 9, -3]
>>> [vec1[i]*vec2[i] for i in range(len(vec1))]
[8, 12, -54]复制代码

列表推导式可使用复杂表达式或嵌套函数:

>>> [str(round(355/113, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']复制代码

5. 嵌套列表解析

Python的列表还能够嵌套。

如下实例展现了3X4的矩阵列表:

>>> matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]复制代码

如下实例将3X4的矩阵列表转换为4X3列表:

>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]复制代码

如下实例也可使用如下方法来实现:

>>> transposed = []
>>> for i in range(4):
...     transposed.append([row[i] for row in matrix])
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]复制代码

另一种实现方法:

>>> transposed = []
>>> for i in range(4):
...     # the following 3 lines implement the nested listcomp
...     transposed_row = []
...     for row in matrix:
...         transposed_row.append(row[i])
...     transposed.append(transposed_row)
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]复制代码

6. del 语句

使用 del 语句能够从一个列表中依索引而不是值来删除一个元素。这与使用 pop() 返回一个值不一样。能够用 del 语句从列表中删除一个切割,或清空整个列表(咱们之前介绍的方法是给该切割赋一个空列表)。例如:

>>> a = [-1, 1, 66.25, 333, 333, 1234.5]
>>> del a[0]
>>> a
[1, 66.25, 333, 333, 1234.5]
>>> del a[2:4]
>>> a[1, 66.25, 1234.5]
>>> del a[:]
>>> a
[]复制代码

也能够用 del 删除实体变量:

>>> del a复制代码

7. 元组和序列

元组由若干逗号分隔的值组成,例如:

>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))复制代码

如你所见,元组在输出时老是有括号的,以便于正确表达嵌套结构。在输入时可能有或没有括号, 不过括号一般是必须的(若是元组是更大的表达式的一部分)。

8. 集合

集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。

能够用大括号({})建立集合。注意:若是要建立一个空集合,你必须用 set() 而不是 {} ;后者建立一个空的字典,下一节咱们会介绍这个数据结构。

如下是一个简单的演示:

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # 删除重复的{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket                 # 检测成员
True
>>> 'crabgrass' in basket
False
>>> # 如下演示了两个集合的操做...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  # a 中惟一的字母
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                              # 在 a 中的字母,但不在 b 中
{'r', 'd', 'b'}
>>> a | b                              # 在 a 或 b 中的字母
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # 在 a 和 b 中都有的字母
{'a', 'c'}
>>> a ^ b                              # 在 a 或 b 中的字母,但不一样时在 a 和 b 中
{'r', 'd', 'b', 'm', 'z', 'l'}复制代码

集合也支持推导式:

>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'r', 'd'}复制代码

9. 字典

另外一个很是有用的 Python 内建数据类型是字典。

序列是以连续的整数为索引,与此不一样的是,字典以关键字为索引,关键字能够是任意不可变类型,一般用字符串或数值。

理解字典的最佳方式是把它看作无序的键=>值对集合。在同一个字典以内,关键字必须是互不相同。

一对大括号建立一个空的字典:{}。

这是一个字典运用的简单例子:

>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
>>> tel['jack']
4098
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
>>> list(tel.keys())
['irv', 'guido', 'jack']
>>> sorted(tel.keys())
['guido', 'irv', 'jack']
>>> 'guido' in telTrue
>>> 'jack' not in telFalse复制代码

构造函数 dict() 直接从键值对元组列表中构建字典。若是有固定的模式,列表推导式指定特定的键值对:

>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}复制代码

此外,字典推导能够用来建立任意键和值的表达式词典:

>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}复制代码

若是关键字只是简单的字符串,使用关键字参数指定键值对有时候更方便:

>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}复制代码

10. 遍历技巧

在字典中遍历时,关键字和对应的值可使用 items() 方法同时解读出来:

>>> knights = {'gallahad': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
...     print(k, v)
...gallahad the pure
robin the brave复制代码

在序列中遍历时,索引位置和对应值可使用 enumerate() 函数同时获得:

>>> for i, v in enumerate(['tic', 'tac', 'toe']):
...     print(i, v)
...
0 tic
1 tac
2 toe复制代码

同时遍历两个或更多的序列,可使用 zip() 组合:

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
...     print('What is your {0}? It is {1}.'.format(q, a))
...
What is your name?  It is lancelot.
What is your quest?  It is the holy grail.
What is your favorite color?  It is blue.复制代码

要反向遍历一个序列,首先指定这个序列,而后调用 reversed() 函数:

>>> for i in reversed(range(1, 10, 2)):
...     print(i)
...
9
7
5
3
1复制代码

要按顺序遍历一个序列,使用 sorted() 函数返回一个已排序的序列,并不修改原值:

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear复制代码

参阅文档

七、Python3 模块

在前面的几个章节中咱们脚本上是用 python 解释器来编程,若是你从 Python 解释器退出再进入,那么你定义的全部的方法和变量就都消失了。

为此 Python 提供了一个办法,把这些定义存放在文件中,为一些脚本或者交互式的解释器实例使用,这个文件被称为模块。

模块是一个包含全部你定义的函数和变量的文件,其后缀名是.py。模块能够被别的程序引入,以使用该模块中的函数等功能。这也是使用 python 标准库的方法。

下面是一个使用 python 标准库中模块的例子。

实例(Python 3.0+)

# 文件名: using_sys.py
 
import sys
 
print('命令行参数以下:')
for i in sys.argv:
   print(i)
 
print('\n\nPython 路径为:', sys.path, '\n')复制代码

执行结果以下所示:

$ python using_sys.py 参数1 参数2
命令行参数以下:
using_sys.py
参数1
参数2


Python 路径为: ['/root', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages'] 
复制代码
  • 一、import sys 引入 python 标准库中的 sys.py 模块;这是引入某一模块的方法。
  • 二、sys.argv 是一个包含命令行参数的列表。
  • 三、sys.path 包含了一个 Python 解释器自动查找所需模块的路径的列表。

1. import 语句

想使用 Python 源文件,只需在另外一个源文件里执行 import 语句,语法以下:

import module1[, module2[,... moduleN]复制代码

当解释器遇到 import 语句,若是模块在当前的搜索路径就会被导入。

搜索路径是一个解释器会先进行搜索的全部目录的列表。如想要导入模块 support,须要把命令放在脚本的顶端:

2. support.py 文件代码

# Filename: support.py
 
def print_func( par ):
    print ("Hello : ", par)
    returntest.py 引入 support 模块:复制代码

3. test.py 文件代码

# Filename: test.py
 
# 导入模块
import support
 
# 如今能够调用模块里包含的函数了
support.print_func("Runoob")复制代码

以上实例输出结果:

$ python3 test.py 
Hello :  Runoob复制代码

一个模块只会被导入一次,无论你执行了多少次import。这样能够防止导入模块被一遍又一遍地执行。

当咱们使用import语句的时候,Python解释器是怎样找到对应的文件的呢?

这就涉及到Python的搜索路径,搜索路径是由一系列目录名组成的,Python解释器就依次从这些目录中去寻找所引入的模块。

这看起来很像环境变量,事实上,也能够经过定义环境变量的方式来肯定搜索路径。

搜索路径是在Python编译或安装的时候肯定的,安装新的库应该也会修改。搜索路径被存储在sys模块中的path变量,作一个简单的实验,在交互式解释器中,输入如下代码:

>>> import sys
>>> sys.path
['', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
>>> 复制代码

sys.path 输出是一个列表,其中第一项是空串'',表明当前目录(如果从一个脚本中打印出来的话,能够更清楚地看出是哪一个目录),亦即咱们执行python解释器的目录(对于脚本的话就是运行的脚本所在的目录)。

所以若像我同样在当前目录下存在与要引入模块同名的文件,就会把要引入的模块屏蔽掉。

了解了搜索路径的概念,就能够在脚本中修改sys.path来引入一些不在搜索路径中的模块。

如今,在解释器的当前目录或者 sys.path 中的一个目录里面来建立一个fibo.py的文件,代码以下:

实例

def fib(n):    # 定义到 n 的斐波那契数列
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()
 
def fib2(n): # 返回到 n 的斐波那契数列
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result复制代码

而后进入Python解释器,使用下面的命令导入这个模块:

>>> import fibo复制代码

这样作并无把直接定义在fibo中的函数名称写入到当前符号表里,只是把模块fibo的名字写到了那里。

可使用模块名称来访问函数:

实例

>>>fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'复制代码

若是你打算常用一个函数,你能够把它赋给一个本地的名称:

>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377复制代码


4. from … import 语句

Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中,语法以下:

from modname import name1[, name2[, ... nameN]]复制代码

例如,要导入模块 fibo 的 fib 函数,使用以下语句:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377复制代码

这个声明不会把整个fibo模块导入到当前的命名空间中,它只会将fibo里的fib函数引入进来。


5. from … import * 语句

把一个模块的全部内容全都导入到当前的命名空间也是可行的,只需使用以下声明:

from modname import *复制代码

这提供了一个简单的方法来导入一个模块中的全部项目。然而这种声明不应被过多地使用。

6. 深刻模块

模块除了方法定义,还能够包括可执行的代码。这些代码通常用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。

每一个模块有各自独立的符号表,在模块内部为全部的函数看成全局符号表来使用。

因此,模块的做者能够放心大胆的在模块内部使用这些全局变量,而不用担忧把其余用户的全局变量搞混。

从另外一个方面,当你确实知道你在作什么的话,你也能够经过 modname.itemname 这样的表示法来访问模块内的函数。

模块是能够导入其余模块的。在一个模块(或者脚本,或者其余地方)的最前面使用 import 来导入一个模块,固然这只是一个惯例,而不是强制的。被导入的模块的名称将被放入当前操做的模块的符号表中。

还有一种导入的方法,可使用 import 直接把模块内(函数,变量的)名称导入到当前操做模块。好比:

>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377复制代码

这种导入的方法不会把被导入的模块的名称放在当前的字符表中(因此在这个例子里面,fibo 这个名称是没有定义的)。

这还有一种方法,能够一次性的把模块中的全部(函数,变量)名称都导入到当前模块的字符表:

>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377复制代码

这将把全部的名字都导入进来,可是那些由单一下划线(_)开头的名字不在此例。大多数状况, Python程序员不使用这种方法,由于引入的其它来源的命名,极可能覆盖了已有的定义。

7. __name__属性

一个模块被另外一个程序第一次引入时,其主程序将运行。若是咱们想在模块被引入时,模块中的某一程序块不执行,咱们能够用__name__属性来使该程序块仅在该模块自身运行时执行。

#!/usr/bin/python3
# Filename: using_name.py

if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另外一模块')复制代码

运行输出以下:

$ python using_name.py
程序自身在运行复制代码
$ python
>>> import using_name
我来自另外一模块
>>>复制代码

说明: 每一个模块都有一个__name__属性,当其值是'__main__'时,代表该模块自身在运行,不然是被引入。

说明:__name____main__ 底下是双下划线, _ _ 是这样去掉中间的那个空格。

8. dir() 函数

内置的函数 dir() 能够找到模块内定义的全部名称。以一个字符串列表的形式返回:

>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)  
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
 '__package__', '__stderr__', '__stdin__', '__stdout__',
 '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
 '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
 'call_tracing', 'callstats', 'copyright', 'displayhook',
 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
 'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
 'thread_info', 'version', 'version_info', 'warnoptions']复制代码

若是没有给定参数,那么 dir() 函数会罗列出当前定义的全部名称:

>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir() # 获得一个当前模块中定义的属性列表
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
>>> a = 5 # 创建一个新的变量 'a'
>>> dir()
['__builtins__', '__doc__', '__name__', 'a', 'sys']
>>>
>>> del a # 删除变量名a
>>>
>>> dir()
['__builtins__', '__doc__', '__name__', 'sys']
>>>复制代码

9. 标准模块

Python 自己带着一些标准的模块库,在 Python 库参考文档中将会介绍到(就是后面的"库参考文档")。

有些模块直接被构建在解析器里,这些虽然不是一些语言内置的功能,可是他却能很高效的使用,甚至是系统级调用也没问题。

这些组件会根据不一样的操做系统进行不一样形式的配置,好比 winreg 这个模块就只会提供给 Windows 系统。

应该注意到这有一个特别的模块 sys ,它内置在每个 Python 解析器中。变量 sys.ps1 和 sys.ps2 定义了主提示符和副提示符所对应的字符串:

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Runoob!')
Runoob!
C> 复制代码

10. 包

包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。

好比一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。

就好像使用模块的时候,你不用担忧不一样模块之间的全局变量相互影响同样,采用点模块名称这种形式也不用担忧不一样库之间的模块重名的状况。

这样不一样的做者均可以提供 NumPy 模块,或者是 Python 图形库。

不妨假设你想设计一套统一处理声音文件和数据的模块(或者称之为一个"包")。

现存不少种不一样的音频文件格式(基本上都是经过后缀名区分的,例如: .wav,:file:.aiff,:file:.au,),因此你须要有一组不断增长的模块,用来在不一样的格式之间转换。

而且针对这些音频数据,还有不少不一样的操做(好比混音,添加回声,增长均衡器功能,建立人造立体声效果),因此你还须要一组怎么也写不完的模块来处理这些操做。

这里给出了一种可能的包结构(在分层的文件系统中):

sound/                          顶层包
      __init__.py               初始化 sound 包
      formats/                  文件格式转换子包
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  声音效果子包
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  filters 子包
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...复制代码

在导入一个包的时候,Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。

目录只有包含一个叫作 __init__.py 的文件才会被认做是一个包,主要是为了不一些滥俗的名字(好比叫作 string)不当心的影响搜索路径中的有效模块。

最简单的状况,放一个空的 :file:__init__.py就能够了。固然这个文件中也能够包含一些初始化代码或者为(将在后面介绍的) __all__变量赋值。

用户能够每次只导入一个包里面的特定模块,好比:

import sound.effects.echo复制代码

这将会导入子模块:sound.effects.echo。 他必须使用全名去访问:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)复制代码

还有一种导入子模块的方法是:

from sound.effects import echo复制代码

这一样会导入子模块: echo,而且他不须要那些冗长的前缀,因此他能够这样使用:

echo.echofilter(input, output, delay=0.7, atten=4)复制代码

还有一种变化就是直接导入一个函数或者变量:

from sound.effects.echo import echofilter复制代码

一样的,这种方法会导入子模块: echo,而且能够直接使用他的 echofilter() 函数:

echofilter(input, output, delay=0.7, atten=4)复制代码

注意当使用 from package import item 这种形式的时候,对应的 item 既能够是包里面的子模块(子包),或者包里面定义的其余名称,好比函数,类或者变量。

import 语法会首先把 item 看成一个包定义的名称,若是没找到,再试图按照一个模块去导入。若是还没找到,抛出一个 :exc:ImportError 异常。

反之,若是使用形如 import item.subitem.subsubitem 这种导入形式,除了最后一项,都必须是包,而最后一项则能够是模块或者是包,可是不能够是类,函数或者变量的名字。

11. 从一个包中导入*

设想一下,若是咱们使用 from sound.effects import *会发生什么?

Python 会进入文件系统,找到这个包里面全部的子模块,一个一个的把它们都导入进来。

可是很不幸,这个方法在 Windows平台上工做的就不是很是好,由于Windows是一个大小写不区分的系统。

在这类平台上,没有人敢担保一个叫作 ECHO.py 的文件导入为模块 echo 仍是 Echo 甚至 ECHO。

(例如,Windows 95就很讨厌的把每个文件的首字母大写显示)并且 DOS 的 8+3 命名规则对长模块名称的处理会把问题搞得更纠结。

为了解决这个问题,只能烦劳包做者提供一个精确的包的索引了。

导入语句遵循以下规则:若是包定义文件 __init__.py 存在一个叫作 __all__ 的列表变量,那么在使用 from package import * 的时候就把这个列表中的全部名字做为包内容导入。

做为包的做者,可别忘了在更新包以后保证 __all__ 也更新了啊。你说我就不这么作,我就不使用导入*这种用法,好吧,没问题,谁让你是老板呢。这里有一个例子,在:file:sounds/effects/__init__.py中包含以下代码:

__all__ = ["echo", "surround", "reverse"]复制代码

这表示当你使用from sound.effects import *这种用法时,你只会导入包里面这三个子模块。

若是 __all__ 真的没有定义,那么使用from sound.effects import *这种语法的时候,就不会导入包 sound.effects 里的任何子模块。他只是把包sound.effects和它里面定义的全部内容导入进来(可能运行__init__.py里定义的初始化代码)。

这会把 __init__.py 里面定义的全部名字导入进来。而且他不会破坏掉咱们在这句话以前导入的全部明确指定的模块。看下这部分代码:

import sound.effects.echo
import sound.effects.surround
from sound.effects import *复制代码

这个例子中,在执行 from...import 前,包 sound.effects 中的 echo 和 surround 模块都被导入到当前的命名空间中了。(固然若是定义了 __all__ 就更没问题了)

一般咱们并不主张使用 * 这种方法来导入模块,由于这种方法常常会致使代码的可读性下降。不过这样倒的确是能够省去很多敲键的功夫,并且一些模块都设计成了只能经过特定的方法导入。

记住,使用 from Package import specific_submodule 这种方法永远不会有错。事实上,这也是推荐的方法。除非是你要导入的子模块有可能和其余包的子模块重名。

若是在结构中包是一个子包(好比这个例子中对于包sound来讲),而你又想导入兄弟包(同级别的包)你就得使用导入绝对的路径来导入。好比,若是模块sound.filters.vocoder 要使用包 sound.effects 中的模块 echo,你就要写成 from sound.effects import echo。

from . import echo
from .. import formats
from ..filters import equalizer复制代码

不管是隐式的仍是显式的相对导入都是从当前模块开始的。主模块的名字永远是"__main__",一个Python应用程序的主模块,应当老是使用绝对路径引用。

包还提供一个额外的属性__path__。这是一个目录列表,里面每个包含的目录都有为这个包服务的__init__.py,你得在其余__init__.py被执行前定义哦。能够修改这个变量,用来影响包含在包里面的模块和子包。

这个功能并不经常使用,通常用来扩展包里面的模块。

八、Python3 输入和输出

在前面几个章节中,咱们其实已经接触了 Python 的输入输出的功能。本章节咱们将具体介绍 Python 的输入输出。

1. 输出格式美化

Python两种输出值的方式: 表达式语句和 print() 函数。

第三种方式是使用文件对象的 write() 方法,标准输出文件能够用 sys.stdout 引用。

若是你但愿输出的形式更加多样,可使用 str.format() 函数来格式化输出值。

若是你但愿将输出的值转成字符串,可使用 repr() 或 str() 函数来实现。

  • str(): 函数返回一个用户易读的表达形式。
  • repr(): 产生一个解释器易读的表达形式。

例如

>>> s = 'Hello, Runoob'
>>> str(s)
'Hello, Runoob'
>>> repr(s)" 'Hello, Runoob'"
>>> str(1/7)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'x 的值为: ' + repr(x) + ', y 的值为:' + repr(y) + '...'
>>> print(s)
x 的值为: 32.5,  y 的值为:40000...
>>> # repr() 函数能够转义字符串中的特殊字符
... hello = 'hello, runoob\n'
>>> hellos = repr(hello)>>> print(hellos)
'hello, runoob\n'
>>> # repr() 的参数能够是 Python 的任何对象
... repr((x, y, ('Google', 'Runoob')))" (32.5, 40000, ('Google', 'Runoob'))"复制代码

这里有两种方式输出一个平方与立方的表:

>>> for x in range(1, 11):
...     print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
...     # 注意前一行 'end' 的使用
...     print(repr(x*x*x).rjust(4))
... 
1   1    1 
2   4    8 
3   9   27 
4  16   64 
5  25  125 
6  36  216 
7  49  343 
8  64  512 
9  81  729
10 100 1000

>>> for x in range(1, 11):
...     print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
... 
1   1    1 
2   4    8 
3   9   27 
4  16   64 
5  25  125 
6  36  216 
7  49  343 
8  64  512 
9  81  729
10 100 1000复制代码

注意:在第一个例子中, 每列间的空格由 print() 添加。

这个例子展现了字符串对象的 rjust() 方法, 它能够将字符串靠右, 并在左边填充空格。

还有相似的方法, 如 ljust() 和 center()。 这些方法并不会写任何东西, 它们仅仅返回新的字符串。

另外一个方法 zfill(), 它会在数字的左边填充 0,以下所示:

>>> '12'.zfill(5)'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'复制代码

str.format() 的基本使用以下:

>>> print('{}网址: "{}!"'.format('菜鸟教程', 'www.runoob.com'))复制代码

括号及其里面的字符 (称做格式化字段) 将会被 format() 中的参数替换。

在括号中的数字用于指向传入对象在 format() 中的位置,以下所示:

>>> print('{0} 和 {1}'.format('Google', 'Runoob'))
Google 和 Runoob
>>> print('{1} 和 {0}'.format('Google', 'Runoob'))
Runoob 和 Google复制代码

若是在 format() 中使用了关键字参数, 那么它们的值会指向使用该名字的参数。

>>> print('{name}网址: {site}'.format(name='菜鸟教程', site='www.runoob.com'))复制代码

位置及关键字参数能够任意的结合:

>>> print('站点列表 {0}, {1}, 和 {other}。'.format('Google', 'Runoob', other='Taobao'))
站点列表 Google, Runoob, 和 Taobao。复制代码

!a (使用 ascii()), !s (使用 str()) 和 !r (使用 repr()) 能够用于在格式化某个值以前对其进行转化:

>>> import math
>>> print('常量 PI 的值近似为: {}。'.format(math.pi))
常量 PI 的值近似为: 3.141592653589793。
>>> print('常量 PI 的值近似为: {!r}。'.format(math.pi))
常量 PI 的值近似为: 3.141592653589793。复制代码

可选项 : 和格式标识符能够跟着字段名。 这就容许对值进行更好的格式化。 下面的例子将 Pi 保留到小数点后三位:

>>> import math
>>> print('常量 PI 的值近似为 {0:.3f}。'.format(math.pi))
常量 PI 的值近似为 3.142。复制代码

在 : 后传入一个整数, 能够保证该域至少有这么多的宽度。 用于美化表格时颇有用。

>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> for name, number in table.items():
...     print('{0:10} ==> {1:10d}'.format(name, number))
...
Google     ==>          1
Runoob     ==>          2
Taobao     ==>          3复制代码

若是你有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时经过变量名而非位置会是很好的事情。

最简单的就是传入一个字典, 而后使用方括号 [] 来访问键值 :

>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> print('Runoob: {0[Runoob]:d}; Google: {0[Google]:d}; Taobao: {0[Taobao]:d}'.format(table))
Runoob: 2; Google: 1; Taobao: 3复制代码

也能够经过在 table 变量前使用 ** 来实现相同的功能:

>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> print('Runoob: {Runoob:d}; Google: {Google:d}; Taobao: {Taobao:d}'.format(**table))
Runoob: 2; Google: 1; Taobao: 3复制代码

2. 旧式字符串格式化

% 操做符也能够实现字符串格式化。 它将左边的参数做为相似 sprintf() 式的格式化字符串, 而将右边的代入, 而后返回格式化后的字符串. 例如:

>>> import math
>>> print('常量 PI 的值近似为:%5.3f。' % math.pi)
常量 PI 的值近似为:3.142。

由于 str.format() 比较新的函数, 大多数的 Python 代码仍然使用 % 操做符。可是由于这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format().

3. 读取键盘输入

Python提供了 input() 内置函数从标准输入读入一行文本,默认的标准输入是键盘。

input 能够接收一个Python表达式做为输入,并将运算结果返回。

实例

str = input("请输入:");
print ("你输入的内容是: ", str)复制代码

这会产生以下的对应着输入的结果:

请输入:菜鸟教程
你输入的内容是:  菜鸟教程复制代码

4. 读和写文件

open() 将会返回一个 file 对象,基本语法格式以下:

open(filename, mode)复制代码
  • filename:包含了你要访问的文件名称的字符串值。
  • mode:决定了打开文件的模式:只读,写入,追加等。全部可取值见以下的彻底列表。这个参数是非强制的,默认文件访问模式为只读(r)。

不一样模式打开文件的彻底列表:

模式 描述
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w 打开一个文件只用于写入。若是该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。若是该文件不存在,建立新文件。
wb 以二进制格式打开一个文件只用于写入。若是该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。若是该文件不存在,建立新文件。
w+ 打开一个文件用于读写。若是该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。若是该文件不存在,建立新文件。
wb+ 以二进制格式打开一个文件用于读写。若是该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。若是该文件不存在,建立新文件。
a 打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容以后。若是该文件不存在,建立新文件进行写入。
ab 以二进制格式打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容以后。若是该文件不存在,建立新文件进行写入。
a+ 打开一个文件用于读写。若是该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。若是该文件不存在,建立新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。若是该文件不存在,建立新文件用于读写。

下图很好的总结了这几种模式:

模式 r r+ w w+ a a+
+ + + +
+ + + + +
建立 + + + +
覆盖 + +
指针在开始 + + + +
指针在结尾 + +

如下实例将字符串写入到文件 foo.txt 中:

实例

# 打开一个文件
f = open("/tmp/foo.txt", "w")
f.write( "Python 是一个很是好的语言。\n是的,的确很是好!!\n" )
# 关闭打开的文件
f.close()复制代码
  • 第一个参数为要打开的文件名。
  • 第二个参数描述文件如何使用的字符。 mode 能够是 'r' 若是文件只读, 'w' 只用于写 (若是存在同名文件则将被删除), 和 'a' 用于追加文件内容; 所写的任何数据都会被自动增长到末尾. 'r+' 同时用于读写。 mode 参数是可选的; 'r' 将是默认值。

此时打开文件 foo.txt,显示以下:

$ cat /tmp/foo.txt 
Python 是一个很是好的语言。
是的,的确很是好!!复制代码

5. 文件对象的方法

本节中剩下的例子假设已经建立了一个称为 f 的文件对象。

f.read()

为了读取一个文件的内容,调用 f.read(size), 这将读取必定数目的数据, 而后做为字符串或字节对象返回。

size 是一个可选的数字类型的参数。 当 size 被忽略了或者为负, 那么该文件的全部内容都将被读取而且返回。

如下实例假定文件 foo.txt 已存在(上面实例中已建立):

实例

# 打开一个文件
f = open("/tmp/foo.txt", "r")
str = f.read()
print(str)
# 关闭打开的文件
f.close()复制代码

执行以上程序,输出结果为:

Python 是一个很是好的语言。
是的,的确很是好!!复制代码

f.readline()

f.readline() 会从文件中读取单独的一行。换行符为 '\n'。f.readline() 若是返回一个空字符串, 说明已经已经读取到最后一行。

实例

# 打开一个文件
f = open("/tmp/foo.txt", "r")

str = f.readline()print(str)

# 关闭打开的文件
f.close()复制代码

执行以上程序,输出结果为:

Python 是一个很是好的语言。复制代码

f.readlines()

f.readlines() 将返回该文件中包含的全部行。

若是设置可选参数 sizehint, 则读取指定长度的字节, 而且将这些字节按行分割。

实例

# 打开一个文件
f = open("/tmp/foo.txt", "r")

str = f.readlines()
print(str)

# 关闭打开的文件
f.close()复制代码

执行以上程序,输出结果为:

['Python 是一个很是好的语言。\n', '是的,的确很是好!!\n']复制代码

另外一种方式是迭代一个文件对象而后读取每行:

实例

# 打开一个文件
f = open("/tmp/foo.txt", "r")

for line in f:    
    print(line, end='')

# 关闭打开的文件
f.close()复制代码

执行以上程序,输出结果为:

Python 是一个很是好的语言。
是的,的确很是好!!复制代码

这个方法很简单, 可是并无提供一个很好的控制。 由于二者的处理机制不一样, 最好不要混用。

f.write()

f.write(string)string 写入到文件中, 而后返回写入的字符数。

实例

# 打开一个文件
f = open("/tmp/foo.txt", "w")

num = f.write( "Python 是一个很是好的语言。\n是的,的确很是好!!\n" )
print(num)
# 关闭打开的文件
f.close()复制代码

执行以上程序,输出结果为:

29复制代码

若是要写入一些不是字符串的东西, 那么将须要先进行转换:

实例

# 打开一个文件
f = open("/tmp/foo1.txt", "w")

value = ('www.runoob.com', 14)
s = str(value)
f.write(s)

# 关闭打开的文件
f.close()复制代码

执行以上程序,打开 foo1.txt 文件:

$ cat /tmp/foo1.txt 
('www.runoob.com', 14)复制代码

f.tell()

f.tell() 返回文件对象当前所处的位置, 它是从文件开头开始算起的字节数。

f.seek()

若是要改变文件当前的位置, 可使用 f.seek(offset, from_what) 函数。

from_what 的值, 若是是 0 表示开头, 若是是 1 表示当前位置, 2 表示文件的结尾,例如:

  • seek(x,0) : 从起始位置即文件首行首字符开始移动 x 个字符
  • seek(x,1) : 表示从当前位置日后移动x个字符
  • seek(-x,2):表示从文件的结尾往前移动x个字符

from_what 值为默认为0,即文件开头。下面给出一个完整的例子:

>>> f = open('/tmp/foo.txt', 'rb+')
>>> f.write(b'0123456789abcdef')
16
>>> f.seek(5)     # 移动到文件的第六个字节
5
>>> f.read(1)
b'5'
>>> f.seek(-3, 2) # 移动到文件的倒数第三字节13
>>> f.read(1)
b'd'复制代码

f.close()

在文本文件中 (那些打开文件的模式下没有 b 的), 只会相对于文件起始位置进行定位。

当你处理完一个文件后, 调用 f.close() 来关闭文件并释放系统的资源,若是尝试再调用该文件,则会抛出异常。

>>> f.close()
>>> f.read()Traceback (most recent call last):  
File "<stdin>", line 1, in ?
ValueError: I/O operation on closed file复制代码

当处理一个文件对象时, 使用 with 关键字是很是好的方式。在结束后, 它会帮你正确的关闭文件。 并且写起来也比 try - finally 语句块要简短:

>>> with open('/tmp/foo.txt', 'r') as f:
...     read_data = f.read()
>>> f.closed
True复制代码

文件对象还有其余方法, 如 isatty() 和 trucate(), 但这些一般比较少用。

6. pickle 模块

python的pickle模块实现了基本的数据序列和反序列化。

经过pickle模块的序列化操做咱们可以将程序中运行的对象信息保存到文件中去,永久存储。

经过pickle模块的反序列化操做,咱们可以从文件中建立上一次程序保存的对象。

基本接口:

pickle.dump(obj, file, [,protocol])复制代码

有了 pickle 这个对象, 就能对 file 以读取的形式打开:

x = pickle.load(file)复制代码

注解:从 file 中读取一个字符串,并将它重构为原来的python对象。

file: 类文件对象,有read()和readline()接口。

实例 1

#!/usr/bin/python3import pickle

# 使用pickle模块将数据对象保存到文件
data1 = {'a': [1, 2.0, 3, 4+6j],'b': ('string', u'Unicode string'),'c': None}

selfref_list = [1, 2, 3]
selfref_list.append(selfref_list)

output = open('data.pkl', 'wb')

# Pickle dictionary using protocol 0.pickle.dump(data1, output)

# Pickle the list using the highest protocol available.
pickle.dump(selfref_list, output, -1)
output.close()复制代码

实例 2

import pprint, pickle

#使用pickle模块从文件中重构python对象
pkl_file = open('data.pkl', 'rb')

data1 = pickle.load(pkl_file)pprint.pprint(data1)

data2 = pickle.load(pkl_file)pprint.pprint(data2)

pkl_file.close()
复制代码

9. Python3 File(文件) 方法

1. open() 方法

Python open() 方法用于打开一个文件,并返回文件对象,在对文件进行处理过程都须要使用到这个函数,若是该文件没法被打开,会抛出 OSError。

注意:使用 open() 方法必定要保证关闭文件对象,即调用 close() 方法。

open() 函数经常使用形式是接收两个参数:文件名(file)和模式(mode)。

open(file, mode='r')复制代码

完整的语法格式为:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)复制代码

参数说明:

  • file: 必需,文件路径(相对或者绝对路径)。
  • mode: 可选,文件打开模式
  • buffering: 设置缓冲
  • encoding: 通常使用utf8
  • errors: 报错级别
  • newline: 区分换行符
  • closefd: 传入的file参数类型
  • opener:

mode 参数有:

模式 描述
t 文本模式 (默认)。
x 写模式,新建一个文件,若是该文件已存在则会报错。
b 二进制模式。
+ 打开一个文件进行更新(可读可写)。
U 通用换行模式(Python 3 不支持)。
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
rb 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。通常用于非文本文件如图片等。
r+ 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+ 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。通常用于非文本文件如图片等。
w 打开一个文件只用于写入。若是该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。若是该文件不存在,建立新文件。
wb 以二进制格式打开一个文件只用于写入。若是该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。若是该文件不存在,建立新文件。通常用于非文本文件如图片等。
w+ 打开一个文件用于读写。若是该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。若是该文件不存在,建立新文件。
wb+ 以二进制格式打开一个文件用于读写。若是该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。若是该文件不存在,建立新文件。通常用于非文本文件如图片等。
a 打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容以后。若是该文件不存在,建立新文件进行写入。
ab 以二进制格式打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容以后。若是该文件不存在,建立新文件进行写入。
a+ 打开一个文件用于读写。若是该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。若是该文件不存在,建立新文件用于读写。
ab+ 以二进制格式打开一个文件用于追加。若是该文件已存在,文件指针将会放在文件的结尾。若是该文件不存在,建立新文件用于读写。

默认为文本模式,若是要以二进制模式打开,加上 b 。

2. file 对象

file 对象使用 open 函数来建立,下表列出了 file 对象经常使用的函数:

序号 方法及描述
1

file.close()

关闭文件。关闭后文件不能再进行读写操做。

2

file.flush()

刷新文件内部缓冲,直接把内部缓冲区的数据马上写入文件, 而不是被动的等待输出缓冲区写入。

3

file.fileno()

返回一个整型的文件描述符(file descriptor FD 整型), 能够用在如os模块的read方法等一些底层操做上。

4

file.isatty()

若是文件链接到一个终端设备返回 True,不然返回 False。

5

file.next()

Python 3 中的 File 对象不支持 next() 方法。

返回文件下一行。

6

file.read([size])

从文件读取指定的字节数,若是未给定或为负则读取全部。

7

file.readline([size])

读取整行,包括 "\n" 字符。

8

file.readlines([sizeint])

读取全部行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行, 实际读取值可能比 sizeint 较大, 由于须要填充缓冲区。

9

file.seek(offset[, whence])

移动文件读取指针到指定位置

10

file.tell()

返回文件当前位置。

11

file.truncate([size])

从文件的首行首字符开始截断,截断文件为 size 个字符,无 size 表示从当前位置截断;截断以后后面的全部字符被删除,其中 Widnows 系统下的换行表明2个字符大小。

12

file.write(str)

将字符串写入文件,返回的是写入的字符长度。

13

file.writelines(sequence)

向文件写入一个序列字符串列表,若是须要换行则要本身加入每行的换行符。


十、Python3 OS 文件/目录方法

os 模块提供了很是丰富的方法用来处理文件和目录。经常使用的方法以下表所示:

序号 方法及描述
1

os.access(path, mode)


检验权限模式
2

os.chdir(path)


改变当前工做目录
3

os.chflags(path, flags)


设置路径的标记为数字标记。
4

os.chmod(path, mode)


更改权限
5

os.chown(path, uid, gid)


更改文件全部者
6

os.chroot(path)


改变当前进程的根目录
7

os.close(fd)


关闭文件描述符 fd
8

os.closerange(fd_low, fd_high)


关闭全部文件描述符,从 fd_low (包含) 到 fd_high (不包含), 错误会忽略
9

os.dup(fd)


复制文件描述符 fd
10

os.dup2(fd, fd2)


将一个文件描述符 fd 复制到另外一个 fd2
11

os.fchdir(fd)


经过文件描述符改变当前工做目录
12

os.fchmod(fd, mode)


改变一个文件的访问权限,该文件由参数fd指定,参数mode是Unix下的文件访问权限。
13

os.fchown(fd, uid, gid)


修改一个文件的全部权,这个函数修改一个文件的用户ID和用户组ID,该文件由文件描述符fd指定。
14

os.fdatasync(fd)


强制将文件写入磁盘,该文件由文件描述符fd指定,可是不强制更新文件的状态信息。
15

os.fdopen(fd[, mode[, bufsize]])


经过文件描述符 fd 建立一个文件对象,并返回这个文件对象
16

os.fpathconf(fd, name)


返回一个打开的文件的系统配置信息。name为检索的系统配置的值,它也许是一个定义系统值的字符串,这些名字在不少标准中指定(POSIX.1, Unix 95, Unix 98, 和其它)。
17

os.fstat(fd)


返回文件描述符fd的状态,像stat()。
18

os.fstatvfs(fd)


返回包含文件描述符fd的文件的文件系统的信息,Python 3.3 相等于 statvfs()。
19

os.fsync(fd)


强制将文件描述符为fd的文件写入硬盘。
20

os.ftruncate(fd, length)


裁剪文件描述符fd对应的文件, 因此它最大不能超过文件大小。
21

os.getcwd()


返回当前工做目录
22

os.getcwdu()


返回一个当前工做目录的Unicode对象
23

os.isatty(fd)


若是文件描述符fd是打开的,同时与tty(-like)设备相连,则返回true, 不然False。
24

os.lchflags(path, flags)


设置路径的标记为数字标记,相似 chflags(),可是没有软连接
25

os.lchmod(path, mode)


修改链接文件权限
26

os.lchown(path, uid, gid)


更改文件全部者,相似 chown,可是不追踪连接。
27

os.link(src, dst)


建立硬连接,名为参数 dst,指向参数 src
28

os.listdir(path)


返回path指定的文件夹包含的文件或文件夹的名字的列表。
29

os.lseek(fd, pos, how)


设置文件描述符 fd当前位置为pos, how方式修改: SEEK_SET 或者 0 设置从文件开始的计算的pos; SEEK_CUR或者 1 则从当前位置计算; os.SEEK_END或者2则从文件尾部开始. 在unix,Windows中有效
30

os.lstat(path)


像stat(),可是没有软连接
31

os.major(device)


从原始的设备号中提取设备major号码 (使用stat中的st_dev或者st_rdev field)。
32

os.makedev(major, minor)


以major和minor设备号组成一个原始设备号
33

os.makedirs(path[, mode])


递归文件夹建立函数。像mkdir(), 但建立的全部intermediate-level文件夹须要包含子文件夹。
34

os.minor(device)


从原始的设备号中提取设备minor号码 (使用stat中的st_dev或者st_rdev field )。
35

os.mkdir(path[, mode])


以数字mode的mode建立一个名为path的文件夹.默认的 mode 是 0777 (八进制)。
36

os.mkfifo(path[, mode])


建立命名管道,mode 为数字,默认为 0666 (八进制)
37

os.mknod(filename[, mode=0600, device])
建立一个名为filename文件系统节点(文件,设备特别文件或者命名pipe)。

38

os.open(file, flags[, mode])


打开一个文件,而且设置须要的打开选项,mode参数是可选的
39

os.openpty()


打开一个新的伪终端对。返回 pty 和 tty的文件描述符。
40

os.pathconf(path, name)


返回相关文件的系统配置信息。
41

os.pipe()


建立一个管道. 返回一对文件描述符(r, w) 分别为读和写
42

os.popen(command[, mode[, bufsize]])


从一个 command 打开一个管道
43

os.read(fd, n)


从文件描述符 fd 中读取最多 n 个字节,返回包含读取字节的字符串,文件描述符 fd对应文件已达到结尾, 返回一个空字符串。
44

os.readlink(path)


返回软连接所指向的文件
45

os.remove(path)


删除路径为path的文件。若是path 是一个文件夹,将抛出OSError; 查看下面的rmdir()删除一个 directory。
46

os.removedirs(path)


递归删除目录。
47

os.rename(src, dst)


重命名文件或目录,从 src 到 dst
48

os.renames(old, new)


递归地对目录进行改名,也能够对文件进行改名。
49

os.rmdir(path)


删除path指定的空目录,若是目录非空,则抛出一个OSError异常。
50

os.stat(path)


获取path指定的路径的信息,功能等同于C API中的stat()系统调用。
51

os.stat_float_times([newvalue])
决定stat_result是否以float对象显示时间戳

52

os.statvfs(path)


获取指定路径的文件系通通计信息
53

os.symlink(src, dst)


建立一个软连接
54

os.tcgetpgrp(fd)


返回与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组
55

os.tcsetpgrp(fd, pg)


设置与终端fd(一个由os.open()返回的打开的文件描述符)关联的进程组为pg。
56

os.tempnam([dir[, prefix]])


Python3 中已删除。返回惟一的路径名用于建立临时文件。
57

os.tmpfile()


Python3 中已删除。返回一个打开的模式为(w+b)的文件对象 .这文件对象没有文件夹入口,没有文件描述符,将会自动删除。
58

os.tmpnam()


Python3 中已删除。为建立一个临时文件返回一个惟一的路径
59

os.ttyname(fd)


返回一个字符串,它表示与文件描述符fd 关联的终端设备。若是fd 没有与终端设备关联,则引起一个异常。
60

os.unlink(path)


删除文件路径
61

os.utime(path, times)


返回指定的path文件的访问和修改的时间。
62

os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])


输出在文件夹中的文件名经过在树中游走,向上或者向下。
63

os.write(fd, str)


写入字符串到文件描述符 fd中. 返回实际写入的字符串长度
64

os.path 模块

获取文件的属性信息。
相关文章
相关标签/搜索