Python

参考资料

Python是一种面向对象、解释性计算机程序设计语言,由Guido van Rossum于1989年底发明,第一个公开版本发行于1991年。Python语法简洁而清晰,具有丰富和强大的类库,它又称为胶水语言,能够轻松的把其他语言制作的模块轻松的连接在一起。

Python是什么呢?

  • Python是一种直译式、交互式、面向对象的计算机编程语言。
  • Python是一种脚本语言、一种交互性语言、一种解释性语言。

注:无需编译源代码称为可执行文件,可直接使用源码运行。

Python语言有什么特点呢?

  • 开源免费
  • 脚本语言 解释执行
  • 跨平台
  • 简介美观
  • 一切皆对象
  • 可扩展的胶水语言

解释执行

在具体计算上实现一种语言,首先需要确定的是表示该语言语义解释的虚拟计算机,一个关键的问题是程序执行时基本表示为实际计算机上的机器语言还是虚拟机的机器语言。这个问题决定了语言的实现,根据这个问题的回答,可以将程序设计语言划分为两大类:编译型语言和解释型语言。

  • 编译实现的语言

比如C、C++、Fortran、Pascal、Ada等,由于编译型语言编写的源代码程序需要经过编译、汇编、链接才能输出目标代码,然后由机器执行目标代码。目标代码是由机器指令组成的,并不能够独立运行,因为源代码程序中可能使用了一些汇编程序不能解释引用的库函数,而库函数又不是在源程序中的,此时还需链接程序完成外部引用和目标模板调用的链接任务,最后才能输出为可执行代码。

  • 解释型语言

解释型语言的解释器不会产生目标机器代码,而是产生中间代码,这种中间代码与机器代码不同,中间代码的解释是由软件支持的,不能直接使用在硬件上。软件解释器通常会导致执行效率低,使用解释型语言编写的程序是由另一个可以理解的中间代码的解释程序执行的。和编译型程序不同的是,解释程序的任务是逐一将源代码的语句解释成可执行的机器指令,无需将源代码翻译成目标代码后再执行。对于解释型语言而言,需要一个专门的解释器来执行该程序。每条语句只有在执行时才能被翻译,这种解释型语言每执行一次就会翻译一次,因而效率低下。

我们这里的解释执行是相对于编译执行而言的,使用C/C++之类的编译性语言编写的程序,是需要从源代码文件转换成计算机使用的机器语言,并经过链接器链接之后形成二进制的可执行文件,运行程序时需要将二进制程序从磁盘载入到内存后执行。

对于Python这种解释型的动态脚本语言而言,是不需要将Python源代码编译成二进制代码的,它可以直接从源代码运行程序。当运行Python文件程序时,Python解释器将源代码转换为字节码,然后再由Python解释器来执行字节码。这样,Python就不用担心程序的编译以及库的链接加载等问题。

Python解析执行原理是什么样的呢?

Python首先会将.py的源代码文件编译成.pyc字节码文件,然后交给字节码虚拟机PVM,字节码虚拟机中的解释器会从编译得到的PyCodeObject对象中一条一条的执行字节码指令,并在当前上下文环境中执行字节码指令,从而完成程序的执行。Python解释器实际上是在模拟操作中执行文件的过程,PyCodeObject对象中包含了字节码指令以及程序的所有静态信息,但并没有包含程序运行时的动态信息 - 执行环境PyFrameObject

4933701-39f6016e51652bdf.png
python解释执行原理

对于Python解释性语言来说,具有以下三方面的特征:

  1. 每次运行都需要转换成字节码,然后再由虚拟机将字节码转换成机器语言,最后才能在硬件上运行。这与编译性语言相比,每次多出了编译和链接的过程,性能上肯定是会受到影响的。
  2. 由于无需关心程序的编译和库的链接等问题,开发工作相对更加轻松。
    3.Python代码与机器底层距离更远,Python程序更易于移植,基本上无需改动就可以在多个平台上运行。

什么是字节码呢?

字节码在Python解释器程序中对应的是PyCodeObject对象,也就是说,Python源代码编译结果就是PyCodeObject对象,PyCodeObject对象的创建时机是模拟加载时以及import时。.pyc文件是字节码在磁盘上的表现形式,如果要生成.pyc文件,可使用Python内置模块py_compile来编译。加载模块时,如果同时存在.py.pyc文件,Python会尝试使用.pyc,如果.pyc的编译时间早于.py的修改时间,则会重新编译.py并更新.pyc文件。

安装配置

Ubuntu下Python开发环境搭建

Python是Linux、Unix、Mac OS X等的重要系统组件,Ubuntu默认自身会安装Python,使用前需检查当前系统中Python的版本。

# 检查python是否已经安装
$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 

# 查看python版本
$ python --version
# 查看python路径
$ whereis python
python: /usr/bin/python3.5 /usr/bin/python3.5m /usr/bin/python2.7 /usr/bin/python /usr/bin/python2.7-config /usr/lib/python3.5 /usr/lib/python2.7 /etc/python3.5 /etc/python2.7 /etc/python /usr/local/lib/python3.5 /usr/local/lib/python2.7 /usr/include/python2.7_d /usr/include/python2.7 /usr/share/python /usr/share/man/man1/python.1.gz
$ which python
/usr/bin/python

Ubuntu安装Python

# 安装python
$ sudo apt-get install python

# 测试运行
$ python
>>> print "python test"

Python交互解释器(交互执行环境)

$ mkdir demo && sudo chmod -R 0777 demo 

$ cd demo && vim test.py
# 获取用户输入
name = raw_input("what is your name?")
print "hello "+name

$ python test.py

语言基础

变量

4933701-fd79afb32d43432c.png
变量

每个变量都存储了一个值,存储着与变量相关联的信息。

$ python
>>> message = "hello world"
>>> print(message)
hello world

程序中可随时修改变量的值,Python始终记录变量的最新值。

$ python
>>> message = "hello world"
>>> print(message)
hello world
>>> print(id(message), type(message))
2603089401200 <class 'str'>
>>> message = "hello python"
>>> print(message)
hello python
>>> print(id(message), type(message))
2603089422256 <class 'str'>

变量的命名

  • 变量名只能包含字母、数字、下划线
  • 变量名可以以字母或下划线打头,但不能以数字大头。
  • 变量名不能包含空格,但可以使用下划线来分割其中的单词。
  • 不用将Python关键字和函数名作为变量名
  • 不用使用Python保留用于特殊用途的单词
  • 变量名应简短却具有描述性,要善于创建有意义的变量名。
  • 变量名慎用小写字母l和大写字母O,因为可能被人看成数字10
  • 建议变量名使用小写字母

使用变量时避免命名错误 NameError

$ python
>>> message = "hello world"
>>> print(mesage)
Traceback (most recent call last):
  File "/test/test.py", line 2, in <module>
    print(mesage)
NameError: name 'mesage' is not defined

程序存在错误时,Python解释器将竭尽所能地帮助你找出问题所在。程序无法成功地运行时,解释器会提供一个tracebacktraceback是一条记录,指出解释器尝试运行代码时,在什么地方陷入了困境。

Python解释器指出,文件test.py的第2行存在错误:NameError: name 'mesage' is not defined。Python无法识别你提供的变量名,名称错误意味着两种情况:要么时使用变量前忘记对它赋值,要么时输入变量名时拼写错误。

变量的作用域

$ vim test.py
def fn(x):
  z = x + y //本地变量 y、z
  return z

x = 1 // 全局变量 x
fn(2)
$ python test.py

变量也是对象,在Python中一切皆对象,变量是对象有自己的属性和方法。

  • 查看对象类型:变量名.class
  • 调用对象方法:变量名.方法()
$ python
>>> var = 1
>>> dir(var)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
>>> var.__class__
<type 'int'>
>>> var.__hex__()
'0x1'

注释

  • 注释使得能够使用自然语言在程序中添加说明
  • 注释使用井号#标识,#后面的内容都会python解释器忽略。
  • 注释的目的是阐述代码要做什么以及是如何做的

Python之禅

$ python
>>> import this
# Python之禅
The Zen of Python, by Tim Peters
# 优美胜过丑陋
Beautiful is better than ugly.
# 显式胜过隐式
Explicit is better than implicit.
# 简单胜过复杂
Simple is better than complex.
# 复杂胜过难懂
Complex is better than complicated.
# 扁平胜过嵌套
Flat is better than nested.
# 稀疏胜过紧密
Sparse is better than dense.
# 可读性应当被重视
Readability counts.
# 尽管实用性会打败纯粹性,特例也不能凌驾于规则之上。
Special cases aren't special enough to break the rules.
Although practicality beats purity.
# 不要忽略任何错误,除非你确定要这么做。
Errors should never pass silently.
Unless explicitly silenced.
# 面对不明确的定义,拒绝猜测的诱惑。
In the face of ambiguity, refuse the temptation to guess.
# 找到一种最好唯一的一种方法去解决问题
There should be one-- and preferably only one --obvious way to do it.
# 虽然一开始这种方法并不是显而易见的,因为你不是Python之父。
Although that way may not be obvious at first unless you're Dutch.
# 做好过不做,但没有思考的做,还不如不做。
Now is better than never.
Although never is often better than *right* now.
- 如果实现很难说明,那它是一个坏想法。
If the implementation is hard to explain, it's a bad idea.
# 如果实现容易解释,那它有可能是个好想法。
If the implementation is easy to explain, it may be a good idea.
# 命名空间是个绝妙的想法,多加利用。
Namespaces are one honking great idea -- let's do more of those!

数据类型

在计算机科学中,数据是指所有能够输入到计算机并被计算机程序处理的符号介质。是用于输入计算机及逆行处理,具有一定意义的数字、字母、符号、模拟量等的统称。现代计算机存储和处理对象十分广泛,表示这些对象的数据也随着变得越来越复杂。

数据是用来表示状态的,不同的状态使用不同类型的数据进行表示,因此在处理不同类型的数据时就需要定义不同的数据类型。

Python中基本数据类型包括数字、字符串、列表、元组、字典、集合六种,其中数字又包含整型、浮点型、复数型、布尔型。而字符串、列表、元组都是序列。

4933701-b35603334949809f.png
Python数据类型
4933701-6b405177857a8fea.png
数据类型
4933701-29020f784ee0d2b0.png
Python数据类型按特征划分
4933701-26634220ee69aff7.png
Python数据类型按可变性划分
4933701-27085e8f90d64bc9.png
Python序列结构

内建数据类型

  • Boolean 布尔类型,真值为True,假值为False
  • Integer 整型
  • Float 浮点型
  • String 字符串型
  • List 列表
  • Tuple 元祖
  • Dict 字典
  • Set 集合
  • None 表示空字符串''、空元素()、空列表[]、空字典{}

容器类型

  • 支持跨行定义
  • 所有对象都有引用计数
  • 列表和字典支持2种类型的复制操作:浅复制、深复制,深复制可使用copy模块中的deepcopy()实现。
  • Python中所有对象都是第一类的 ,这意味着使用标识符命名的所有对象都具有相同状态,于是能够命名的对象都可以直接当作数据进行处理。
  • 所有序列都支持迭代
  • 所有序列都支持的操作方法:索引、切片、扩展切片、长度、最小值、最大值、求和...
  • 可变序列的操作:索引元素赋值、切片赋值
$ vim test.py
import sys
a = 1
ll = [1,2,3,4]
sys.getrefcount(a)
sys.getrefcount(ll)

Number数字

Bool布尔

计算机的本质是计算,在其内部是0和1的比特位的变化,对外表现为数据的变化。本质上,数据都是以字节Byte存储的,表现上他们就是下整型、浮点

  • Python中使用布尔型使用bool来表示,主要用途是辨别真假。
  • Python中使用bool辨别真假时除了0表示假值False外,其他值被认为是正值True,包括None和空。
Integer整数
  • 对可整数执行加+-*/运算
  • 使用两个乘号**表示乘方
  • 使用括号()修改运算次序
  • 空格不影响计算表达式的方式,它的存在是为了阅读代码时能更快速确定先执行那些运算。
x = 1
y = 2

print(x + y, x - y, x * y, x / y, x ** y)
# 3 -1 2 0.5 1
Float浮点数
  • 带小数点的数字称为浮点数,小数点可出现在数字的任何位置。
  • 浮点算术计算的结果包含的小数位数可能时不确定的
x = 0.1
y = 0.2

print(x + y, x - y, x * y, x / y, x ** y)
# 0.30000000000000004 -0.1 0.020000000000000004 0.5 0.6309573444801932

使用str()函数避免类型错误

num = 18
str = "Happy "+num+"rd Birthday!"

Traceback (most recent call last):
  File "/test/test.py", line 2, in <module>
    str = "Happy "+num+"rd Birthday"
TypeError: must be str, not int

类型错误TypeError,意味着Python无法识别你所使用的信息。

num = 18
str = "Happy "+str(num)+"rd Birthday!"
print(str)

String字符串

  • 字符串是一系列字符,在Python中使用引号括起来的都是字符串,引号可以是单引号也可以是双引号。
  • 字符串是不可变的,也就是说改变一个字符串的元素需要创建一个新的字符串。
  • 字符串是由独立的字符组成的,这些字符可以通过切片操作来顺序地访问。
  • Python中可使用“原始字符串”操作符来创建直接量字符串
  • Python中没有字符这种类型,单个字符在Pythoon中也是作为一个字符串使用。
  • Python中实际上有三种字符串,分别包括通常意义上的字符串、Unicode字符串、抽象类basestring的子类。
  • Python中访问子串可使用方括号[]进行截取

修改字符串的大小写

  • title() 将首字母修改为大写
  • upper() 将字母转换为大写
  • lower() 将字母转换为小写
$ python
>>> message = "hello world"
>>> print(message)
hello world
>>> print(message.title())
Hello World
>>> print(message.upper())
HELLO WORLD
>>> print(message.lower())
hello world

很多时候,你是无法依靠用户来提供正确的大小写的,因此需要将字符串先转换为小写后存储,在需要的时候在转换为合适的大小写。

合并拼接字符串

Python中使用+加号来合并字符串,这种合并字符串的方式叫做拼接。

$ python
>>> str = "Hello"
>>> fullname = "jun chow"
>>> print(str + " " + fullname.title() + "!")
Hello Jun Chow!

使用制表符或换行符来添加空白

在编程中,空白泛指任何非打印字符,如空格\s、制表符\t、换行符\n

$ python
>>> message = "Name:\n\talice\n\tbob\n\tcarl"
>>> print(message)
Name:
    alice
    bob
    carl

删除空白

程序中,额外的空白会令人迷惑。空白很重要,因为经常会需要比较两个字符串是否相同。另外,这些剔除函数最常用在存储用户输入前对其进行清理。

  • strip() 删除字符串两端的空白
  • rstrip() 删除字符串末尾右边的空白
  • lstrip() 删除字符串开头左边的空白
$ python
>>> str = " hello python "
>>> print(len(str))
14
>>> print(len(str.strip()), str.strip())
12 hello python
>>> print(len(str.lstrip()), str.lstrip())
13 hello python 
>>> print(len(str.rstrip()), str.rstrip())
13  hello python

使用字符串时避免语法错误

程序中如果包含非法的Python代码时会导致语法错误SyntaxError

$ python
>>> str = ' hello python "
  File "/test/test.py", line 1
    str = ' hello python "
                         ^
SyntaxError: EOL while scanning string literal

List列表

Python内置数据类型列表List,List是一种有序集合,可随时添加和删除其中元素。

  • 列表由一系列按特定顺序排列的元素组成,换言之列表是有序集合。
  • 列表中的元素之间可以没有任何关系
  • 鉴于列表包含多个元素,给列表指定表示复数的名称是个不错的实践。
  • 列表使用方括号[]表示,并用逗号,分隔其中的元素。
languages = ["python", "c", "shell"]
print(languages)
# ['python', 'c', 'shell']
# 进入python交互式解释器
$ python

# 创建list列表
>>> lst = ['alice', 'ben', 'carl']

# 查看list列表
>>> lst 

# 查看list列表长度
>>> len(lst)

# 查看list元素
>>> lst[0]
>>> lst[-1]

# list列表是一个可变有序表,可向list追加元素到末尾
>>> lst.push('dan')

# 向指定下标位置插入元素
>>> lst.insert(1, 'junchow')

# 删除list列表末尾元素
>>> lst.pop()

# 删除指定位置元素
>>> lst.pop(1)

# 替换元素
>>> lst[1]='apple'

字符串和列表的转换

$ python
>>> str = "hello world"
>>> list = str.split()
>>> list.append("!")
>>> str = string.join(list[1:3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'string' is not defined

insert/pop/sort/index/remove/del...

$ python
>>> help(dict)
>>> help(str)

列表的不可变性

  • 列表是可变对象,字符串是不变对象。
  • 列表可变对象操作时,列表内部内容是会发生变化的。
  • 对于不可变对象字符串操作后并不会改变其内容

例如:

$ python
>>> mylist = ['d', 'c', 'b', 'g']
>>> mylist.sort()
>>> mylist

$ python
>>> str = "this is a demo"
>>> str.replace("is", "at")
>>> str

访问列表元素

  • 列表是有序集合,要访问列表中的元素只需要将指定元素的位置或索引即可。
languages = ["python", "c", "shell"]
print(languages, languages[0], languages[len(languages)-1])
# ['python', 'c', 'shell'] python shell
  • 列表元素的索引是从0开始而不是1开始,访问最后一个元素可将索引指定为-1即可,依此类推。
languages = ["python", "c", "shell"]
print(languages, languages[0], languages[len(languages)-1], languages[-1])
# ['python', 'c', 'shell'] python shell shell
  • 使用列表中的各个值,可以像使用变量一样使用列表中的各个值。
languages = ["python", "c", "shell"]
print("My first language was " + languages[0].title() + ".")
# My first language was Python.

修改列表元素

  • 多数列表是将是动态的,列表创建后将随着程序的运行增减元素,列表的长度将不断变化。
  • 修改列表元素与访问列表元素语法类似,指定列表名和要修改元素的索引后再为该元素赋新值。
languages = ["python", "c", "shell"]
languages[0] = "lua"
print(languages)
# ['lua', 'c', 'shell']

列表追加元素

  • append() 在列表末尾添加新元素,而不影响列表中其它所有元素。
languages = ["python", "c", "shell"]
languages[0] = "lua"
languages.append("c++")
print(languages)
# ['lua', 'c', 'shell', 'c++']
  • 使用append()动态地创建列表
heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

列表插入元素

  • insert()可在列表的任何位置添加新元素,需指定新元素的索引和值,插入操作将列表中既有的每个元素都右移一个位置。
heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

heroes.insert(0, "black panther")
print(heroes)
# ['black panther', 'spider man', 'iron man', 'captain american', 'black widow', 'hulk']

heroes.insert(-1, "cable")
print(heroes)
# ['black panther', 'spider man', 'iron man', 'captain american', 'black widow', 'cable', 'hulk']
4933701-cb168d7a403b586f.png
列表

列表删除元素

  • del 语句删除元素,需指定待删除的元素在列表中的位置。
  • 使用del语句将值从列表中删除后,就无法再访问它了。
heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

del heroes[0]
print(heroes)
# ['iron man', 'captain american', 'black widow', 'hulk']

del heroes[-1]
print(heroes)
# ['iron man', 'captain american', 'black widow']
  • 使用pop()函数删除元素,并返回删除的元素的值。
  • pop()函数可以删除列表末尾的元素,并能接着使用它。
  • 列表像是一个栈,删除列表末尾的元素相当于弹出栈顶的元素。
heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

hero = heroes.pop()
print(heroes, hero)
# ['spider man', 'iron man', 'captain american', 'black widow'] hulk

hero = heroes.pop(0)
print(heroes, hero)
# ['iron man', 'captain american', 'black widow'] spider man

hero = heroes.pop(-1)
print(heroes, hero)
# ['iron man', 'captain american'] black widow

根据值删除元素

若只知道需要删除元素的值而不知道元素在列表中的位置,可使用remove()删除。

heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

heroes.remove("iron man")
print(heroes)
# ['spider man', 'captain american', 'black widow', 'hulk']
4933701-5eba9bc25915dbe6.png
列表方法

组织列表

在创建列表时元素的排列顺序是无法预料的,但经常会需要以特定的顺序呈现。有时又希望保留列表元素最初的排列顺序,有时候又需要调整排列顺序。

列表排序

  • 使用sort()对列表进行永久排序,默认为升序方式。
  • 使用sort(reverse=True)改变排序方式为降序
heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

heroes.sort()
print(heroes)
# ['black widow', 'captain american', 'hulk', 'iron man', 'spider man']

heroes.sort(reverse=True)
print(heroes)
# ['spider man', 'iron man', 'hulk', 'captain american', 'black widow']
  • 使用sorted()对列表进行临时排序,保留列表元素原来的排列顺序,同时以特定的顺序呈现。
  • 使用sorted(list, reverse=True)对列表临时降序排序
heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

list = sorted(heroes)
print(heroes, list)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk'] ['black widow', 'captain american', 'hulk', 'iron man', 'spider man']

list = sorted(heroes, reverse=True)
print(heroes, list)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk'] ['spider man', 'iron man', 'hulk', 'captain american', 'black widow']

列表反转

  • 使用reverse()反转列表元素的排列顺序
  • reverse()将永久性地改变列表元素的排列顺序
heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

heroes.reverse()
print(heroes)
# ['hulk', 'black widow', 'captain american', 'iron man', 'spider man']

列表长度

  • 使用len()确定列表的长度,python计算列表元素时是从1开始的。
heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

len = len(heroes)
print(len)
# 5

使用列表时避免索引错误

heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

索引错误IndexError:列表的索引是从0开始的

print(heroes[len(heroes)])
Traceback (most recent call last):
  File "test.py", line 10, in <module>
    print(heroes[len(heroes)])
IndexError: list index out of range

操作列表

遍历列表

当需要遍历列表中每个元素,可使用for循环。

heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

for hero in heroes:
    print(hero.title())
# Spider Man
# Iron Man
# Captain American
# Black Widow
# Hulk

循环是让计算机自动完成重复工作的常用方式之一,循环时对列表中的每个元素,都将执行循环指定的步骤,不管列表包含多少个元素。在循环中,使用单复数分别表示元素和列表,是一个非常好的实践。

for循环中,每个缩进的代码行都是循环体的一部分,将针对列表中的每个值都会执行一次。

heroes = []
heroes.append("spider man")
heroes.append("iron man")
heroes.append("captain american")
heroes.append("black widow")
heroes.append("hulk")
print(heroes)
# ['spider man', 'iron man', 'captain american', 'black widow', 'hulk']

for hero in heroes:
    print(hero.title() + " Hehe...")
    print(hero.capitalize() + "\n")
# Spider Man Hehe...
# Spider man
# 
# Iron Man Hehe...
# Iron man
# 
# Captain American Hehe...
# Captain american
# 
# Black Widow Hehe...
# Black widow
# 
# Hulk Hehe...
# Hulk

避免缩进错误

  • 忘记缩进
  • 忘记缩进额外的代码行
  • 不必要的缩进
  • 循环后不必要的缩进
  • 遗漏了冒好
for hero in heroes:
print(hero.title() + " Hehe...")
    print(hero.capitalize() + "\n")

缩进错误IndentationError

  File "test.py", line 11
    print(hero.title() + " Hehe...")
        ^
IndentationError: expected an indented block

为避免意外缩进错误,请只缩进需要缩进的代码。

for hero in heroes:
    print(hero.title() + " Hehe...")
    print(hero.capitalize() + "\n")

    print("the end")

从语法上看,代码是合法的,但由于存在逻辑错误,结果并不符合预期。

# Spider Man Hehe...
# Spider man
# 
# the end
# Iron Man Hehe...
# Iron man
# 
# the end
# Captain American Hehe...
# Captain american
# 
# the end
# Black Widow Hehe...
# Black widow
# 
# the end
# Hulk Hehe...
# Hulk
# 
# the end

遗漏了冒好将导致语法错误 SyntaxError

for hero in heroes
    print(hero.title() + " Hehe...")
    print(hero.capitalize() + "\n")
print("the end")
  File "test.py", line 10
    for hero in heroes
                     ^
SyntaxError: invalid syntax

数字列表

列表非常适合存储数字集合,python提供很多工具函数帮助高效地处理数字列表。

  • range() 生成一系列数字
  • range()从指定的第一个值开始数,在到达指定的第二个值后停止,因此是不包含第二个值得。
for item in range(1,3):
    print(item)
# 1
# 2
  • 使用range()创建数字列表,可使用list()range()的结果直接转换为列表。
print(list(range(1,10)))
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
  • 使用range()时可指定步长
print(list(range(1, 10, 2)))
# [1, 3, 5, 7, 9]

print(list(range(0, 10, 2)))
# [0, 2, 4, 6, 8]

squares = []
for item in range(1, 11):
    squares.append(item**2)
print(squares)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

数字列表统计

对数字列表执行简单的统计计算

  • min() 获取数字列表中最小值
  • max() 获取数字列表中最大值
  • sum() 获取数组列表中的总和
list = []
for item in range(1, 11):
    list.append(item**2)
print(list)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

min = min(list)
print(min)
# 1

max = max(list)
print(max)
# 100

sum = sum(list)
print(sum)
# 385

列表解析

列表解析会将for循环和创建新元素的代码合并为一行,并自动附加新元素,用来生成列表。

list = [item**2 for item in range(1, 11)]
print(list)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

列表切片

  • 处理列表的部分元素又称为切片
  • 创建切片时可指定要使用的第一个元素和最后一个元素的索引
  • range()函数一样,python在到达指定的第二个索引前面的元素后停止。
list = [item**2 for item in range(1, 11)]
print(list)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

piece = list[0:5]
print(piece)
# [1, 4, 9, 16, 25]

如果没有指定第一个起始索引则默认从列表开头开始

piece = list[:5]
print(piece)
# [1, 4, 9, 16, 25]

如果要让切片终止于列表末尾,可不用指定第二个结束索引。

piece = list[5:]
print(piece)
# [36, 49, 64, 81, 100]

如果不指定起始索引和结束索引,则会返回原列表。

piece = list[:]
print(piece)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

负数索引可以返回离列表末尾相应距离的元素

piece = list[-5:]
print(piece)
# [36, 49, 64, 81, 100]

遍历切片

如果要遍历列表中的部分元素,可以在for循环中使用切片。

for item in list[0:5]:
    print(item)

复制列表

要复制列表可创建一个包含整个列表的切片,方法是同时省略起始索引和终止索引[:]

list = [item**2 for item in range(1, 11)]
print(list)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

copy = list[:]
print(copy)
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Tuple元组

List和Tuple是Python内置的有序集合,一个可变一个不可变。Tuple元组是一种有序列表,Tuple和List非常类似,Tuple一旦初始化就不能修改。不可变的元组由于不可变所以代码更加安全。

>>> tuple = ('Apple', 'Microsoft', 'Google')

列表适用于存储在程序运行期间可能变化的数据集,列表是可以修改的。有时需要创建一系列不可修改的元素,元组可以满足这种需求。Python中将不能修改的值称为不可变的,而不可变的列表被称为元组。

定义元组

元组使用圆括号()标识,定义元组后就可以使用索引来访问元素,和访问列表元素一样。

tuple = (400, 300)
print(tuple[0], tuple[1])
# 400 300

为元组元素赋值将会导致类型错误TypeError,python中不能给元组的元素赋值。

tuple = (400, 300)
tuple[0] = 100

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    tuple[0] = 100
TypeError: 'tuple' object does not support item assignment

遍历元组中的所有值

和列表一样可以使用for循环来遍历元组中的元素

tuple = (400, 300)
for item in tuple:
    print(item)

修改元组变量

虽然不能修改元组的元素,但可以给存储元素的变量赋值。

tuple = (400, 300)
print(tuple)
# (400, 300)

tuple = (200, 100)
print(tuple)
# (200, 100)

相比于列表,元组是更简单的数据结构,如果需要存储的一组值在程序的整个生命周期内都是不变得,可使用元组。

Dict字典

Python内置字段Dict的支持,其他语言中称为map,使用键值存储,具有较快的查找速度。

字典的使用

  • 字典名 = {"关键字":值, ...}
  • 字典名.get("关键字", 默认值)
  • 字典名["关键字"] = 值

例如:

$ python
>>> user_dict = {"id":10, "name":"alice"}
>>> user_dict.get("id")
10
>>> user_dict.get("gender", 1)
1
>>> user_dict.get("gender")
>>> user_dict["gender"] = 1
>>> user_dict.get("gender")
1
>>> user_dict.keys()
['gender', 'id', 'name']
>>> user_dict.values()
[1, 10, 'alice']
>>> user2_dict = user_dict.copy()
>>> del user2_dict["name"]
>>> user2_dict.popitem()

例如:根据学生名查找成绩

$ vim test.py
map={'alice':100, 'ben':90, 'carl':80}
print map['alice']

为什么字典查找速度这么快呢?因为字典实现原理和查字典一样。

  • 一页一页翻直到找到未知
  • 首先会在字典的索引表里查找字对应的页码

根据字典的Key查找对应的Value,成立返回值,错误返回None。

map.get(''alice')

根据字典的键名删除对应的键值对

map.pop('alice')

注:字典内部存放的顺序和键名key放入的顺序并没有关系

字典与列表相比,字典的优势在哪里呢?

  • 查找和插入速度快,不会随着键的增加而增加。
  • 需占用大量内存,内存浪费多

字典与列表相比,列表的优势是什么呢?

  • 查找和插入的时间随着元素增加而增加
  • 占用空间小浪费内容小

综上所述,字典是一种以空间换时间的方式,字典可用在需要高速查询的地方,字典中的键必须是不可变对象。因为字典会根据键名计算键值的存储位置,若每次计算相同键名得出结果不同,那么字典内部就完全混乱这个通过键名计算位置的算法(哈希算法hash)。因此为保证哈希的正确性,作为键名的对象不能改变。

Python中字典是一系列的键值对,每个键都与一个值相关联,可使用键来访问与之关联的值。与键相关联的值可以是数字、字符串、列表、字典。事实上,可将任何Python对象用作字典的值。

  • 字典使用花括号{}包裹的一系列键值对来表示
  • 键值对是两个相关联的值,指定键时将返回与之关联的值。
  • 键和值之间使用冒号:分隔,键值对之间使用逗号,分隔。
  • 访问字典中的值,只需要指定字典名。
  • 字典中可包含任意数量的键值对
dict = {"user_id":10000, "username":"junchow"}
print(dict)
# {'user_id': 10000, 'username': 'junchow'}
print(dict["user_id"])
# 10000
print(dict["username"])
# junchow
  • 键值对的排列顺序与添加顺序不同,python不关心键值对的添加顺序,只关心键值对之间的关联关系。
dict = {"user_id":10000, "username":"junchow"}
dict["gender"] = 1
print(dict)
# {'user_id': 10000, 'username': 'junchow', 'gender': 1}
  • 字典是一种动态结构,可随时在其中添加键值对。
  • 修改字典中的值,可依次指定字典名、用方括号括起来的键、与该键相关联的新值。
dict = {}
dict["user_id"] = 10000
dict["username"] = "junchow"
dict["gender"] = 1
print(dict)
# {'user_id': 10000, 'username': 'junchow', 'gender': 1}
  • 删除键值对,可使用del语句将相应的键值对彻底删除。
  • del语句时必须指定字典名和要删除的键
del dict["gender"]
print(dict)
# {'user_id': 10000, 'username': 'junchow'}
  • 由类似对象组成的字典,使用字典来存储众多对象的同一种信息。
dict = {}
dict["american capitain"] = "steven steve roger"
dict["hulk"] = "robert bruce banner"
dict["spider man"] = "peter benjamin parker"
dict["iron man"] = "anthony edward tony stack"
print(dict)
# {'american capitain': 'steven steve roger', 'hulk': 'robert bruce banner', 'spider man': 'peter benjamin parker', 'iron man': 'anthony edward tony stack'}

遍历字典

  • 遍历所有键值对
    编写用于遍历字典的for循环,可声明两个变量,用于存储键值对中的键和值。对于这两个变量,可使用任何名称。
dict = {}
dict["cn"] = "china"
dict["ca"] = "canada"

for key,val in dict.items():
    print(key, val)
  • 遍历字典中所有的键
dict = {}
dict["cn"] = "china"
dict["ca"] = "canada"

for key in dict.keys():
    print(key)

方法keys()并非只能用于遍历,实际上,它返回一个列表,包含字典中所有的键。

dict = {}
dict["cn"] = "china"
dict["ca"] = "canada"

print(dict.keys())
# dict_keys(['cn', 'ca'])
  • 按顺序遍历字典中的所有键

字典总是明确地记录键和值之间的关联关系,但获取字典的元素时,获取顺序是不可预测的。要以特定的顺序返回元素,可以在for循环中对返回的键进行排序。

dict = {}
dict["cn"] = "china"
dict["ca"] = "canada"
dict["en"] = "english"

for item in sorted(dict.keys()):
    print(item)
  • 遍历字典中的所有值

可使用方法values()返回一个值的列表,而不包含任何键。

dict = {}
dict["cn"] = "china"
dict["ca"] = "canada"
dict["en"] = "english"

for item in dict.values():
    print(item)

使用values()提取字典中所有的值,而没有考虑是否重复。为剔除重复项可使用集合set,集合类似于列表,但每个元素都必须是独一无二的。

dict = {}
dict["cn"] = "china"
dict["usa"] = "america"
dict["ca"] = "canada"
dict["en"] = "english"
dict["us"] = "america"

for item in set(dict.values()):
    print(item)

通过对包含重复元素的列表调用set(),可让python找出列表中独一无二的元素,并使用这些元素来创建一个集合。结果是一个不重复的列表。

嵌套

有时候,需要将一系列字典存储在列表中,或将列表作为值存储在字典中,这称为嵌套。

字典列表

# 创建空白列表
list = []
# 循环存储
for item in range(10):
    dict = {"id":item, "name":"alice"}
    list.append(dict)
# 分片打印
for item in list[:5]:
    print(item)
# 打印输出
print("total : " + str(len(list)))

在字典中存储列表

有时候需要将列表存储在字典中,而不是将字典存储在列表中。

每当需要在字典中将一个键关联到多个值时,都可以在字典中嵌套一个列表。

dict = {}
dict["language"] = ["python", "java", "lua"]
dict["gender"] = ["male", "female"]
print(dict)
# {'language': ['python', 'java', 'lua'], 'gender': ['male', 'female']}
dict = {}
dict["language"] = ["python", "java", "lua"]
dict["gender"] = ["male", "female"]
print(dict)

for key,val in dict.items():
    print(key + ":")
    for item in val:
        print(item)

在字典中存储字典

可在字典中嵌套字典

Set集合

什么是集合呢?

  • 集合是一组无序排列可以哈希的值
  • 支持集合关系测试、成员关系测试(innot in)、支持迭代,不支持索引、不支持元素获取、不支持切片。

集合与字典有什么异同点呢?

集合和字典类似,也是一组键的集合,但集合并不存储键值。由于键名不能重复,所以集合中不会存在重复的键。集合和字典唯一区别在于集合并没有存储对应的键值。集合和字典是一样的,同样不可以放入可变对象。因为集合无法判断两个可变对象是否相等, 也就无法保证集合内部不会存在重复元素。

集合类型

  • 非可变集合set
  • 不可变集合 frozenset

集合的创建

集合没有特定格式,只能通过工厂函数set进行创建。

例如:创建一个集合可提供一个列表作为输入集合,重复元素会自动过滤。

$ python
>>> help(set)
>>> set1 = set([1,2,3])
>>> print(type(set1))

添加元素

例如:添加元素到集合中

$ python
>>> set = set([1,2,3,4])
>>> set.add(10)

集合运算

  • 集合可看成数学意义上的无需和无重复元素的集合,因此两个集合可作为数学意义上的集合运算。
$ python
>>> s1 = set([1,2,3,4,5])
>>> s2 = set([2,3,2,4,1])
# 计算差集
>>> s1 & s2
# 计算并集
>>> s1 | s2
4933701-f34b667469cd4de6.png
集合操作
$ python
>>> set1 = set([1,2,3])
>>>set2 = set([2,3,4])
>>> print(set1 & set2)
set([2, 3])
>>> print(set1.intersection(set2))
set([2, 3])
>>> print(set1.symmetric_difference(set2)) 
set([1, 4])
>>> print(set1 ^ set2) 
set([1, 4])
>>> print(set1.union(set2)) 
set([1, 2, 3, 4])
>>> print(set1 | set2) 
set([1, 2, 3, 4])
>>> print(set("abc")) 
set(['a', 'c', 'b'])

集合类型的方法和操作

  • len(set) 返回集合中的项目个数
  • s.copy() 制作集合的副本
  • s.difference(t) 求差集,返回所有在集合set中但不在t中的元素。
  • s.intersection(t) 求交集,返回所有同时在s和t中的元素
  • s.isdisjoin(t) 如果s和t没有相同项则返回True
  • s.issubset(t) 如果s是t的子集则返回True
  • s.issuperset(t) 如果s是t的超集则返回True
  • s.symmetric_difference(t) 求对称差集,返回所有在s或t中但又不同时在这两个集合中的元素。
  • s.union(t) 求并集,返回所有在s或t中的元素
$ python
>>> print(set1.pop()) 
1
>>> print(len(set1))
3
>>> print(max(set1)) 
3
>>> print(min(set1)) 
1
>>> print(set1.update(set2))
>>> print(set1)
>>> print(id(set1), id(set2))
>>> print(set1.add(10), set1)
(None, set([1, 2, 3, 10]))
>>> print(set1.add("hello"), set1)
(None, set([1, 2, 3, 10, 'hello']))

流程控制

条件判断

$ vim age.py
age = 20
if age>18:
  print "your age is",age
  print "aduit"
elif age>6:
  print "teenager"
else:
  print "adult"

$ python age.py

条件测试

每条if语句的核心是一个值为TrueFalse的表达式,这种表达式被称为条件测试。Python根据条件测试的值为TrueFalse来决定是否执行if语句中的代码。如果条件测试的值为True,Python就执行紧跟在if语句后面的代码。如果为False,Python就会忽略这些代码。

检查是否相等

多数条件测试都是将一个变量的当前值与特定值进行比较,最简单的条件测试是检查变量的值是否与特定值相等。

car = "bmw"
print(car == "bmw") # True

if car == "bmw":
    print("success") # success

使用两个等号==检查变量的值是否与特定值相等,这个相等运算符在它两边的值相等时返回True,否则返回False

检查是否相同时不考虑大小写

car = "bmw"
print(car == "BMW") # False
print(car.lower() == "bmw") # True

Python中检查相等时是区分大小写的,注意lower()函数不会修改存在变量中的值,因此这种比较不会影响原来的值。

在账户注册时,为保证账户的独一无二,而并非只是与另一个账户的大小写不同。可使用此种方式进行比较检查。

检查是否不相等

要判断两个值是否不相等,可使用!=,其中!惊叹号表示不。

car = "bmw"
print(car != "BMW") # True

在编写多数条件表达式时都会检查两个值是否相等,但有时候检查两个值是否不相等的效率会更高。

比较数字

条件语句中可以包含各种数学比较,如小于<、小于等于<=、大于>、大于等于>=

检查多个条件

有时需要同时检查多个条件,此时关键字andor可以实现。

使用and检查多个条件

要检查多个条件都为True,可使用关键字and将多个条件测试合二为一,如果每个测试都通过了,整个表达式就为True。如果至少有一个测试没有通过,整个表达式就为False

age = 18
gender = 1
print(age == 18 and gender == 1) # True
print((age == 18) and (gender == 1)) # True

为改善可读性,可将每个测试都分别放在一对括号内,但并非必须这样做。

使用or检查多个条件

关键字or能够检查多个条件,只有至少一个条件满足,才能通过整个测试。仅当两个测试都没有通过时,使用or的表达式才为False

age = 18
gender = 1
print(age == 18 or gender == 1) # True
print((age == 18) or (gender == 1)) # True

检查特定值是否包含在列表中

有时在执行操作前必须检查列表中是否包含特定的值,要判断特定值是否已经包含在列表中,可使用关键字in

list = ["hulk", "ironman", "superman", "spiderman", "batman"]
print("robin" in list) # False

检查特定值是否不包含在列表中

有时候确定特定值未包含在列表中很重要,此时就可以使用关键字not in

list = ["hulk", "ironman", "superman", "spiderman", "batman"]
print("robin" not in list) # True

布尔表达式

布尔表达式只不过是条件测试的别名,与条件表达式一样,布尔表达式的结果要么是True,要么是False

if语句

简单的if语句,只有一个测试和一个操作。

if condition_test:
    do something

if语句中,缩进的作用与for循环相同,若测试通过将执行if语句后面所有缩进的代码行,否则将忽略它们。

if-else语句
if-elis-else 结构
使用多个elif代码块

省略else代码块

测试多个条件 if-elif-else结构功能强大,但仅适合用于只有一个条件满足的情况。

循环

$ vim test.py
list = ["alice", "ben", "carl"]
for name in list:
  print name
$ python test.py

计算1到100整数和

$ vim test.py
range = range(100)
sum = 0

for x in range:
  sum += x
print sum

$ python test.py

计算100以内奇数和

$ vim test.py
sum = 0
n = 99

while n>0:
  sum += n
  n = n - 2
print sum

用户输入判断输出

$ vim test.py
age = raw_input("please input your age ")
age = (int)age

if age>18:
  print "adult"
elif age>6:
  print "teenager"
else:
  print "kid"

$ python test.py

raw_input()读取的内容永远以字符串形式返回,把字符串和整数比较是不会得到期待的结果。

函数

程序中,函数是一种最基本的代码抽象的方式。

调用函数,需根据函数的定义,传入正确的参数,若函数调用出错,多看错误信息。

定义函数使用def

$ vim test.py
def func(x):
  if (x): 
    return x
  else: 
    return -x

i = int(inpt_raw('please input number '))
print func(i)

空函数

def nop():
  pass

pass 可用作占位符,现在没想好,可先做一个pass,让代码能运行出来。

  • 定义函数时需确定函数名和参数个数
  • 若有必要需对参数的数据类型做检查
  • 函数体内可用return随时返回函数结果
  • 函数执行完毕无return自动return None
  • 函数可同时返回多个值其实是一个tuple

函数参数

定义函数时,将函数名和位置确定后函数接口定义就完成了。对于函数调用者来说仅需知道如何传递正确的参数,以及函数将要返回的值即可。函数内部的复杂逻辑将被封装起来,使用者无需了解。

$ vim test.py
def power(x, n=2):
  s = 1
  while n>0:
     n = n -1
     s = s * x
  return x
$ python test.py

定义默认参数牢记,默认参数必须指定不变对象。

为什么要设计strNone这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。因此,由于对象不变,多任务环境下同时读取对象无需加锁,同时读一点问题都没有。编写程序时,若可设计一个不变对象就尽量设计成不变对象。

可变参数

函数中可定义可变参数,可变参数是传入的参数个数是可变的,可是任意个或0个。由于参数不确定,可使用listtuple作为参数传入。此种方式需提前构造参数,而使用可变参数,则可大大简化流程。

$ vim test.py
def calc(*num):
  s = 0
  for n in num:
    s = s + n*n
  return s

print calc(1,2,3,4,5)

numlist = [3,2,1,4,5,2]
print calc(*numlist)

Python允许在列表list或元组tuple前添加星号*,将listtuple的元素转换为可变参数传入。

在函数定义中使用*argskwargs传递可变长的参数,*args用来作传递非命名键值可变长参数列表(位置参数),kwargs用来作传递键值可变长参数列表。

*args

*args本质上是将函数传入的参数存储在元组类型的变量args

$ vim args.py
#!/usr/bin/env python
# -*- coding:utf-8 -*-

def fn(arg, *args):
    print("arg = %s"%arg)
    for val in args:
        print("args value = %s"%val)

fn(1, "two", 3)
$ python args.py
arg = 1
args value = two
args value = 3

关键字参数

可变参数允许传入0或任意个参数,这些可变参数在函数调用时自动组装成一个tuple元组。

关键字参数允许用户传入0或任意个含参数名的参数,关键字参数在函数内部自动组装为一个dict字典。

$ vim test.py
# 定义带关键字参数的函数是可行的,问题是太繁琐,所以Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去:
def person(name,age,**kw):
  print 'name:',name,'age:',age,'other:',kw
# 可传入任意个数关键字参数
person('junchow', 30)

关键字参数有什么用呢?可扩展函数的功能。

例如:用户注册时,除了账户和年龄必填其他为可选项,可利用关键字参数来定义函数。

与可变参数类似,可先组装一个dict字典,然后将该dict转换为关键字参数传入。

$ vim test.py
# 定义带有可变参数的函数
def person(name,age,**kw):
  print 'name"',name,'age',age,'other:',kw

# 使用dict字典作为参数
kw = {'city':'Bejing', 'job':'Engineer'}
person('alice', 29, **kw)

**kargs

**kargs本质是将函数的参数和值存储到字典类型的kargs变量中

$ vim kargs.py
#!/usr/bin/env python
# -*- coding:utf=8 -*-

def fn(arg,  **kargs):
    print("arg = %s"%arg)
    for key in kargs.keys():
        print("key = %s val = %s"%(key, kargs[key]))

fn(1, name="alice", id=100)
$ python kargs.py
arg = 1
key = name val = alice
key = id val = 100

参数组合

python中定义函数可用必选参数、默认参数、可变参数、关键字参数,这4中参数可一起使用。

参数定义的顺序必须是 必选参数>默认参数>可变参数>关键字参数

# 创建函数
def fn(a,b,c=0,*args,**kw):
  print 'a=',a,'b=',b,'c=',c,'args=',args,'kw=',kw
//调用函数
fn(1, 2, 3, 'a', 'b', x=99)

对于任意函数,均可通过类似 func(*args, **kw)的形式调用,无论其参数是如何定义的。

  • python函数具有非常灵活的参数形式
  • 默认参数一定要用不可变对象,
  • *args是可变参数,args接收的是一个tuple元组
  • **kw是关键字参数,kw接收一个dict字典

调用函数时如何传入可变参数和关键字参数

  • 可变参数即可直接传入,又可先组装list或tuple在通过*args传入
  • 关键字参数可直接传入,又可先组装**kw传入

使用 *args 和 **kw 是python习惯写法

递归函数

函数内部可调用其他函数,若函数内部调用自身,此函数就是递归函数。

模块加载

模块是包含函数、类、变量等独立的python文件

例如:导入模块

# 导入模块
import module_name
 
# 使用模块中的函数
module_name.function_name()
$ vim module.py
def plus(x, y):
  return x + y

$ vim test.py
import module
print module.plus(1, 2)

例如:导入模块并使用模块中的函数

from module_name import function_name

function_name()

例如:导入系统模块

import sys.path
from os import *

import string, re
import time, random
import socket, threading

time.sleep(1)

print uname()[-1]
# ImportError: No module named path
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值