#Python特点
跨平台,可运行在 Windows、Linux、MacOS
极为强大而丰富的标准库与第三方库
面向对象的语言。解释型语言。有动态脚本特性。
两个变量的交换
a, b = b, a
Python环境准备
Python下载
Python官网:https://www.python.org/
Python文档下载地址:https://www.python.org/doc/
Python安装
Unix & Linux 平台安装Python
- 打开 WEB 浏览器访问https://www.python.org/downloads/source/
- 选择适用 于Unix/Linux 的源码压缩包。
- 下载及解压压缩包。
- 如果你需要自定义一些选项修改Modules/Setup
- 执行 ./configure 脚本
- make
- make install
执行以上操作后,Python 会安装在 /usr/local/bin 目录中,Python 库安装在 /usr/local/lib/pythonXX,XX 为你使用的 Python 的版本号。
Window 平台安装Python
-
打开 WEB 浏览器访问https://www.python.org/downloads/windows/
-
在下载列表中选择Window平台安装包,包格式为:python-XYZ.msi 文件 , XYZ 为你要安装的版本号。
-
下载后,双击下载包,进入 Python 安装向导,安装非常简单,你只需要使用默认的设置一直点击”下一步”直到安装完成即可。
MAC 平台安装 Python
MAC 系统一般都自带有 Python2.x版本 的环境,你也可以在链接 https://www.python.org/downloads/mac-osx/ 上下载最新版安装。
Python环境变量配置
在Unix & Linux设置环境变量
-
在 csh shell:
输入
setenv PATH "$PATH:/usr/local/bin/python"
, 按下”Enter”。
-
在 bash shell (Linux):
输入
export PATH="$PATH:/usr/local/bin/python"
,按下”Enter”。
-
在 sh 或者 ksh shell:
输入
PATH="$PATH:/usr/local/bin/python"
, 按下”Enter”。
注意: /usr/local/bin/python 是 Python 的安装目录。
在Window 设置环境变量
在命令提示框中(cmd) : 输入
path=%path%;C:\Python
按下”Enter”。
注意: C:\Python 是Python的安装目录。
也可以通过可视化界面进行设置:
- 右键点击”计算机”,然后点击”属性”
- 然后点击”高级系统设置”
- 选择”系统变量”窗口下面的”Path”,双击即可!
- 然后在”Path”行,添加python安装路径即可(我的D:\Python32),所以在后面,添加该路径即可。 ps:记住,路径直接用分号”;”隔开!
- 最后设置成功以后,在cmd命令行,输入命令”python”,就可以有相关显示。
Python的几个重要的环境变量
变量名 | 描述 |
---|---|
PYTHONPATH | PYTHONPATH是Python搜索路径,默认我们import的模块都会从PYTHONPATH里面寻找。 |
PYTHONSTARTUP | Python启动后,先寻找PYTHONSTARTUP环境变量,然后执行此变量指定的文件中的代码。 |
PYTHONCASEOK | 加入PYTHONCASEOK的环境变量, 就会使python导入模块的时候不区分大小写. |
PYTHONHOME | 另一种模块搜索路径。它通常内嵌于的PYTHONSTARTUP或PYTHONPATH目录中,使得两个模块库更容易切换。 |
运行Python
三种方式可以运行Python
交互式解释器
通过命令行窗口进入Python,并在交互式解释器中开始编写Python代码。
可以在Unix、DOS或任何其他提供了命令行或者shell的系统进行Python编码工作。
$ python #Unix/Linux
或者
C:>python #Windows/DOS
以下为Python命令行参数:
选项 | 描述 |
---|---|
-d | 在解析时显示调试信息 |
-O | 生成优化代码(.pyo 文件) |
-S | 启动时不引入查找Python路径的位置 |
-V | 输出Python版本号 |
-X | 从1.6版本之后基于内建的异常(仅仅用于字符串)已过时 |
-c cmd | 执行Python脚本,并将运行结果作为cmd字符串 |
file | 在给定的python文件执行python脚本 |
命令行脚本
在你的应用程序中通过引入解释器可以在命令行中执行Python脚本,如下所示:
$ python script.py # Unix/Linux
或者
C:>python script.py # Windows/DOS
注意:在执行脚本时,请检查脚本是否有可执行权限。
继承开发环境(IDE:Integrated Development Environment):PyCharm
PyCharm 是由 JetBrains 打造的一款 Python IDE,支持 macOS、 Windows、 Linux 系统。
PyCharm 功能 : 调试、语法高亮、Project管理、代码跳转、智能提示、自动完成、单元测试、版本控制……
PyCharm 下载地址 : https://www.jetbrains.com/pycharm/download/
PyCharm 安装地址:http://www.runoob.com/w3cnote/pycharm-windows-install.html
数据类型
Number数字
-
整数:int
-
浮点数:float
-
复数:complex 虚部以一个大J或者j来结尾
-
bool:True(非 0) False( 0 )
bool(0)、bool(‘’)、bool([])、bool(())、bool({})、bool(None)都是 False
a=10
type(a)
#结果 <class 'int'>
b=2.5
type(b)
#结果 <class 'float'>
c=3+6j
type(c)
#结果 <class 'complex'>
d=3<2
type(d)
#结果 <class 'bool'>
组
序列·字符串(不可变)
单引号,双引号,三引号(可以是三个单引号,也可以是三个双引号)( 序列 )
索引:mystr1[索引值] 从左向右 从0开始,还可以填写负数,从末尾开始
切片操作:左闭右开 mystr1[开始 :结尾]
字符串不支持修改其内部的数据
字符串可以使用加号进行拼接,可以使用乘法多次重复
mystr='abc'
print (mystr)
#结果 abc
mystr="hello"
print (mystr)
#结果 hello
mystr='''hello'''
print (mystr)
#结果 hello
mystr="""hello world"""
print (mystr)
#结果 hello world
type('1')
#结果 <class 'str'>
mystr='hello world'
mystr[0]
#结果 'h'
mystr[2]
#结果 'l'
mystr[-1]
#结果 'd'
mystr[-2]
#结果 'l'
# 切片操作
mystr[0:3]
#结果 'hel'
mystr[1:]
#结果 'ello world'
mystr[:-1]
#结果 'hello worl'
mystr[-1:]
#结果 'hello worl'
mystr1='abc'
mystr2='efg'
mystr1+mystr2
#结果 'abcefg'
mystr1*3
#结果 'abcabcabc'
python 建议每行字符串长度为 79,如果要换行则可以用三引号进行换行,再用三引号来结束字符串定义。
三引号字符串中包含转义字符,IDLE 会直接当成内容输出。把包含转义字符的三引号字符串放到 print 内进行输出,转义字符会生效。
三引号的内的转义字符会失效,可以达到换行的效果
单引号、双引号的换行
`hello\
world`
#字符串前加 r、R 表示原始字符串,即所见即所得
print(r'c:\windows')
#结果 'c:\windows'
print(R'c:Windows')
#结果 'c:\Windows'
#得到 ascll 码值
ord('w')
#结果 119
max('hello world')
#结果 'w'
序列·列表(有序)
【理解成java中数组。用”[]、list”表示】
创建一个中括号 使用:
mylist = [1,2,3,4,[1,2,3],’abc’,1.5]
切片操作:左闭右开 list[开始 :结尾]
索引:mylist [索引值] 从左向右 从0开始,还可以填写负数,从末尾开始
列表可以使用加号进行拼接,可以使用乘法多次重复
列表支持修改其内部的数据
mylist=['a','b','c',1,2,3]
print (mylist)
#结果 ['a','b','c',1,2,3]
mylist[0]
#结果 'a'
mylist[-1]
#结果 3
# 切片操作
mylist[0:5]
#结果 ['a','b','c',1,2]
# 俩列表相加-->拼接
mylist1=[1,2,3]
mylist2=[4,5,6]
mylist1+mylist2
#结果 [1,2,3,4,5,6]
# 列表乘以数字
mylist=['abc',1,2,3]
mylist*2
#结果 ['abc',1,2,3,'abc',1,2,3]
# 列表某项改值
mylist=[1,2,3]
mylist[0]=100
mylist[0]
#结果 100
列表:
列表是一个有序,可修改的,元素以逗号分割,以中括号包围的序列。
- 几种表达方式:
- list()
- []
- range
- xrange
L=list('abc')
L1=[1,2,3]
L2=range(100)
L3=list(xrang(10))
print type(L)
#结果 <type 'list'>
print type(L1)
#结果 <type 'list'>
pring type(L2)
#结果 <type 'list'>
print L3
#结果 [0,1,2,3,4,5,6,7,8,9]
- 列表索引
L=[1,2,3,4,5,6]
print L
#结果 [1,2,3,4,5,6]
print L[0]
#结果 1
print L[-1]
#结果 6
#切片操作得到的还是列表
print L[1:6]
#结果 [2,3,4,5,6]
print L[1:6:2]
#结果 [2,4,6]
print L[::]
#结果 [1,2,3,4,5,6]
print L[::-1]
#结果 [6,5,4,3,2,1]
print L[-1:-6:-1]
#结果 [6,5,4,3,2]
- 列表的方法
方法名 | 说明 |
---|---|
cmp | 比较两个列表元素,一样返回0,前面元素的值大于后面元素的值,返回1,否则返回-1 |
max | 返回列表当中的最大值 |
min | 返回列表当中的最小值 |
append | 在列表末尾添加新的元素(列表末尾增加一个数据项) |
count | 统计某个元素在列表中出现的次数 |
extend | 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来列表)(列表末尾增加一个数据项集合) |
index | 从列表中找出某个值第一个匹配项的索引位置 |
insert | 将对象插入列表;第一个参数是索引号,第二个参数是待添加的新元素:(在某个特定位置前增加一个数据项) |
pop | 默认移除列表中最后一个元素(并返回该元素的值),也可以带索引 |
remove | 移除列表中某个值的第一个匹配项(找到并删除一个特定的数据项) |
reverse | 反向列表中的元素 |
sorted | 对原列表进行排序 |
序列·元组(不可变)
【理解成Java中的数组+不可变属性】
【复杂的列表,用”()”】
创建一个小括号 使用:
mytuple = (1,2,3,4,[1,2,3],’abc’,1.5)
索引:mytuple[索引值]从左向右 从0开始,还可以填写负数,从末尾开始
切片操作:左闭右开 tuple[开始 :结尾]
元组可以使用加号进行拼接,可以使用乘法多次重复
元组不支持修改其内部的数据
mytuple=(1,2,3,[1,2,3],'wer')
print (mytuple)
#结果 (1,2,3,[1,2,3],'wer')
mytuple[0]
#结果 1
mytuple[-2]
#结果 [1,2,3]
# 切片操作
mytuple[2:5]
#结果 (3,[1,2,3],'wer')
mytuple1=('a','b','c')
mytuple2=(1,2,3,4,)
# 相加--》拼接
mytuple1+mytuple2
#结果 ('a','b','c',1,2,3,4)
# 乘以数字
mytuple2*2
#结果 (1,2,3,4,1,2,3,4)
# 不支持修改其内部数据,会报错
mytuple[0]=123
#结果
# Traceback (most recent call last):
# File "<stdin>", line1, in <module>
# TypeError: 'tuple' object does not support item assignment
元组元素以逗号分割、以小括号包围的有序的,不可修改的序列。
元组和列表的区别:
元组和列表类似,不同的是元组不可修改(其内部的“指向不变”),以小括号()包围,而列表是可修改的,以中括号[]包围。
- 元组的创建:
- tuple()
- ()
t=tuple('123')
t2=(1,2,3)
print t
#结果 ('1','2','3')
print type(t)
#结果 <type 'tuple'>
print type(t2)
#结果 <type 'tuple'>
- 元组的索引
和列表、字符串的索引完全一样
t=(1,2,3,4,5,6)
print t[0]
#结果 1
print t[-1]
#结果 6
print t[::]
#结果 (1,2,3,4,5,6)
print t[0:5:2]
#结果 (1,3,5)
print t[::-1]
#结果 (6,5,4,3,2,1)
元组的特性:
- 元组可以不加括号
- 单元素元组必须加括号
1,2
#结果 (1,2)
1,
#结果 (1,)
type((1))
#结果 <type 'int'>
type((1,))
#结果 <type 'tuple'>
#只有一个元素,IDLE 把括号当成是要运算
type((1))
#结果 <class 'int'>
type(('1'))
#结果 <class 'str'>
#只有一个元素,要表示成元组,则加个“,”
type((1,))
#结果 <class 'tuple'>
#表示空元组
type(())
#结果 <class 'tuple'>
type([1])
#结果 <class 'list'>
集合·set(无序、去重)
-
集合:
可变集合
可以添加和删除元素
不可变集合
不可以添加和删除元素 -
集合的创建:
- set() 可变集合
s=set('hello')
print s
#结果 set(['h','e','l','o'])
print type(s)
#结果 <type 'set'>
print type({1,2,3,4})
#结果 <type 'set'>
- frozenset() 不可变集合
s1 = frozenset('hello')
print s1
#结果 frozenset(['h','e','l','o'])
print type(s1)
#结果 <type 'frozenset'>
-
集合的特性:
集合可以去重
集合无序 -
访问集合:
集合当中没有索引的概念,所以我们需要去遍历访问当中的值
-
更新集合:
因为集合当中没有索引概念,所以我们只能通过内置方法来进行添加和删除元素
可变集合是可以被修改的
不可变集合是不可以被修改的访问 set中的某个元素实际上就是判断一个元素是否在set中。我们可以用 in 操作符判断
s=set(['Adam','Lisa','Bart','Paul'])
s.add('ABC')
print s
s.update('ABC')
print s
#移除元素
s.remove('A')
print s
# in 操作符判断
'Bart' in s
#结果 True
'Bill' in s
#结果 False
# 集合的长度
print len({1,2,3})
#结果 3
#两个集合的差集
print {1,2,3,4,5,6} - {3,4}
#结果 {1,2,5,6}
#两个集合的交集
print {1,2,3,4,5,6} & {3,4,7}
#结果 {3,4}
#两个集合的并集
print {1,2,3,4,5,6} | {3,4,7}
#结果 {1,2,3,4,5,6,7}
# 空的集合
print type(set())
#结果 <class 'set'>
字典·dict(也是一种集合)
-
定义:
字典是一个元素以键值对形式,以逗号分割,以大括号包围的无序的,可以修改的序列。
-
创建字典:{}
d={'name':'json','age':20}
print d
#结果 {'age':20,'name':'json'}
print type(d)
#结果 <class 'dict'>
print type({})
#结果 <class 'dict'>
d = dict([('A',1),('B',2),('C',3)])
print d
#结果 {'A':1,'C':3,'B':2}
# 空的字典
print type({})
#结果 <type 'dict'>
- 两个相同 key,后者会覆盖前者,最终只保留最后一个
- value 可以是任意类型。key 类型必须是不可变类型(int、str、元组)。
进制
-
二进制需要
0b
开头比如:0b10
-
八进制
0o
开头 -
十六进制
0x
开头
进制转换
其他进制转二进制 bin(10) –》0b1010,bin(0o7)–》0b111
其他进制转十进制 int(0b111)–》7
其他进制转十六进制 hex(888)–》0xfff
其他进制转八进制 oct(0b111)–》0o7
作业
-
去除2个列表中的重复元素并按从大到小排序
-
打印出一个字典的所有键值对
# 根据如下dict: d={ 'Adam':95, 'Lisa':85, 'Bart':59 } #请打印出: Adam:95 Lisa:85 Bart:59
-
请设计一个字典,根据用户数据的分数来查找对应的KEY
请设计一个dict,可以根据分数来查找名字,已知成绩如下: Adam:95, Lisa:85, Bart:59.
- 月份也可以用set表示,请设计一个set并判断用户输入的月份是否有效。
月份可以用字符串’Jan’, ‘Feb’, …表示。
(‘Jan’, ‘Feb’, ‘Mar’, ‘Apr’, ‘May’, ‘Jun’,‘Jul’,‘Aug’,‘Sep’,‘Oct’,‘Nov’,‘Dec’)
根据用户的输入的内容来判断用户输入的是否是月份。
变量
区分大小写;
python 保留关键字不能用来当变量名;
python 变量没有类型限制,所有类型的值都可以赋值给变量(动态语言的一个特性)
a=1
b=a
a=3
print(b)
#结果 1 (int 值类型)
a=[1,2,3,4,5]
b=a
a[0]='1'
print(b)
#结果 ['1',2,3,4,5] (list 引用类型)
id(变量名) #取变量的地址
命名建议多个单词之间用下划线隔开
常量
python 不存在常量(因为没法阻止变量改值)
形式上的常量:(约定)变量名改为全大写
Module
python 上一个文件就是一个module(模块),每个模块最上方应该有三引号来写的说明
模块共享(PyPI)
Python 包索引(Python Package Index,PyPI)
BIF
BIF | BIF 的作用 |
---|---|
list() | 这是一个工厂函数,创建一个新的空列表 |
range() | 返回一个迭代器,根据需要生成一个指定范围的数字 |
enumerate() | 创建成对数据的一个编号列表,从 0 开始 |
int() | 将一个字符串或另一个数转换为一个整数(如果可行) |
id() | 返回一个 Python 数据对象的唯一标识 |
next() | 返回一个可迭代数据结构(如列表)中的下一项 |
表达式
表达式(Expression)是运算符(operator)和操作数(operand)所构成的序列
函数编程
函数的定义
将我们的代码进行结构整合,形成了可被我们调用的代码块。
函数的优势
-
函数可以重复调用
-
减少冗余代码
-
代码结构更加清晰
-
有助于我们代码的一致性
定义函数:
def 函数名(参数):
代码块
- 关键字(def)
- 函数名
命名规范:
字母开头
不允许关键字
不允许有特殊符号
参数:
定义在参数括号里,是在调用的时候传入,作用在我们函数内部
如果没有参数,直接写空括号就可以
函数的调用
函数在没有调用的情况不会去执行
函调的调用是 函数名加括号,如果有参数,将括号当中传入相应的参数
实参:就是在我们调用函数的时候,括号当中传递的参数
形参:就是我们定义函数的时候
def Func():
print 'This is test'
Func()
#输出
This is test
def Func(name):
print 'My name is &s, This is my test!'%name
Func('json')
#输出
My name is json, This is my test!
函数划分
- 位置参数:
在我们传参的时候,实参传递的顺序按照形参定义的顺序进行传递的传参方式
def Func(name, age):
print 'My name is %s, I am $s years old!'%(name, age)
Func('json', 20)
- 关键参数
在我们传参的时候,以形参等于实参的形式进行传递的传参方式
def Func(name, age):
print 'My name is %s, I am $s years old!'%(name, age)
Func(name='json', age=20)
Func(age=20, name='json')
- 默认参数(缺省参数)
在我们定义参数的时候,给参数一个默认值,如果在调用函数的时候,
没有给这个有默认值的形参传递实参,那就会自动采用默认值
def Func(name, age=20):
print 'My name is %s, I am $s years old!'%(name, age)
Func('json')
Func('json', 22)
Func(name='json', age=22)
注:默认值参数必须写在正常参数的后面
- 参数组(不定长参数)
元组参数组 *args
给形参前面添加* 使参数变成一个元组,所有传递的参数变成元组的元素
def Func(*args):
print args
Func(1)
Func(1, 2, 3, 4, 5)
- 字典参数组 *kwargs
给形参前面添加* 使参数变成一个字典,所有传递的参数变成字典的键值对,传递的时候要求键等于值的形式
def Func(\**kwargs):
prin kwargs
Func(A = 1)
Func(A = 1, B = 2, C = 3)
函数的返回值
return
函数返回值,不带值的 return 相当于返回 None
def Func(a, b)
return a + b
print Func(10, 10)
其他函数和函数的作用域
匿名函数:
lambda 我们在定义函数的时候,不想给函数起名,那么就可以用lambda来定义一个匿名函数
语法:
lambda 参数:表达式
参数:以逗号分隔的变量表达式形式
表达式:不能有循环
L = [1, 2, 3]
# map(函数,可迭代对象)
F = lambda num:num * num
print map(F, L)
# 输出结果
[1,4,9]
L = [1, 2, 3]
s = '123456'
# map(函数,可迭代对象)
F = lambda num: num * num
print map(F, map(int, s))
# 输出结果
[1,4,9,16,25,36]
# 匿名函数
list = map(lambda x:x*x, [1,2,3,4,5,6])
for i in list:
print(i)
# 输出结果
1
4
9
16
25
36
高阶函数
高阶函数:即是把函数作为参数的函数
def add(x,y,f):
return f(x)+f(y)
print (add(-3,5,abs))
# 输出结果
8
map()
map() 是 Python 内置的高阶函数,
它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。
# 计算f(x)=x*x
def f(x):
return x*x
print map(f, [1,2,3,4,5,6,7,8,9])
#输出结果
[1,4,9,16,25,36,49,64,81]
reduce()
reduce()也是 Python 内置的一个高阶函数。reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值
# 编写一个函数,接收x和y,返回x和y的和
def f(x,y):
return x+y
reduce(f, [1,3,5,7,9])
#输出结果 25
#结果分析:f(1,3)=4,再计算 f(4,5)=9,再计算 f(9,7)=16,再计算 f(16,9)=25
#上面的计算实际就是对 list 的所有元素的求和。虽然 Python 内置了 sum()函数,但用 reduce()求和也很简单
#reduce()还可以接收 3 个可选参数,作为计算的初始值。如果把 初始值设为 100,计算:
def f(x,y):
return x+y
reduce(f, [1,3,5,7,9], 100)
#结果将变为 125,因为第一轮计算为 f(100,1)=101,之后再计算 f(101,3)=104,...最后 f(116,9)=125
# python3 需要从 functools 模块导入,Python2 不用
from functools import reduce
def f(x,y):
return x+y
MyList = reduce(f, [1,2,3,4,5,6])
print(MyList)
#结果:
21
filter()
filter()函数是 Python 内置的另一个有用的高阶函数,filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,
filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list.
# 要从一个 list[1,4,6,7,9,12,17]中删除偶数,保留奇数
#首先,写一个判断奇数的函数
def is_odd(x):
return x%2==1
#然后,利用 filter()过滤偶数:
filter(is_odd, [1,4,6,7,9,12,17])
#结果:
[1,7,9,17]
def ous(x):
return x%2==1
MyList = filter(ous, [1,2,3,4,5,6,7,8])
for i in MyList
print(i)
#输出结果
1
3
5
7
迭代器和生成器
可迭代对象: 可以用循环语句循环的对象就是可迭代对象
迭代器:
可以通过next()逐个的获取下一个元素
iter() 将迭代对象转换为迭代器iter()
next() 返回容器的下一个元素
python next()
# 迭代器
L = [1,2,3,4]
L1 = iter(L)
print L1
# print L1.next()
# print L1.next()
# print L1.next()
# print L1.next()
for i in L1:
print i
函数的作用域
这里关于作用域主要要说下面三个点:
全局作用域的作用范围仅限于单个文件,一个文件就是一个大的作用域,如果我们说有两个文件有同样的一个变量,为了避免这两个变量重复导致我们无法准确的使用其中的一个变量,我们可以使用不同文件的作用域来准确定位我们想要的那个变量,虽然他们名字是一样的,这个在之后,我们会称作模块。
每次函数的调用都会生成一个新的本地作用域
赋值的变量名除非声明为全局变量或非本地变量,否则均为本地变量
在默认情况下,所有函数定义内部的变量名是位于本地作用域内的,如果要在一个函数内部操作一个位于全局的变量名,我们需要在函数内部给变量名使用 global声明,
首先是两种基本的变量的作用域:
局部作用域
全局作用域
global 把局部变量声明为全局变量
zip函数
zip函数:将序列对应索引位上的元素分到一个元组当中,形成一个列表,子元组的个数取决于你的最短序列的长度
d=dict(zip('ABCDE',range(1,6)))
print d
#结果 {'A':1,'C':3,'B':2,'E':5,'D':4}
print type(d)
#结果 <type 'dict'>
d=dict(zip('ABCDE',range(1,5)))
print d
#结果 {'A':1,'C':3,'B':2,'D':4}
print type(d)
#结果 <type 'dict'>
Fromkeys
Fromkeys:以后面的序列的元素为键,默认值为None
print {}.fromkeys('ABCDE')
#结果 {'A':None,'C':None,'B':None,'E':None,'D':None}
print {}.fromkeys('ABCDE','a')
#结果 {'A':'a','C':'a','B':'a','E':'a','D':'a'}
-
字典的特性:
字典是无序的,所以字典没有索引值,无序存储
字典没有索引值,所以制字典以键取值
字典以键取值,所以字典的键唯一并且不可修改
字典的键不可修改,所以列表和字典不可以给字典做键
D = dict(zip('ABCDE',range(1,6)))
print D
#结果 {'A':1,'C':3,'B':2,'E':5,'D':4}
print D['A']
#结果 1
print D['B']
#结果 2
D['A']='a'
print D
#结果 {'A':'a','C':3,'B':2,'E':5,'D':4}
类型 | 方法 | 说明 |
---|---|---|
字典的取值 | keys | 获取字典所有的键 |
.. | values | 获取字典所有的值 |
.. | get | 以键取值,如果键不存在的话,返回None,可以指定返回内容 |
.. | update | |
.. | setdefault | |
.. | items | |
字典的删除 | pop | 弹出,返回并删除指定键对应的值 |
.. | popitem | 随机弹出一个键值元组并删除,这里随机的原因是因为字典无序 |
.. | clear | 清空字典 |
字典的判断 | in | 判断指定的键是否在字典当中 |
-
深浅可拷贝
深拷贝:拷贝所有对象(父级对象和子对象)
浅拷贝:只拷贝父级对象
import copy
a=[1,2,3,4,['a','b']] # 原始对象
b=a #赋值,传对象的引用
c=copy.copy(a) #对象拷贝,浅拷贝
d=copy.deepcopy(a) #对象拷贝,深拷贝
a.append(5) #修改对象a
a[4].append('c') #修改对象a中的['a','b']数组对象
print 'a = ', a
print 'b = ', b
print 'c = ', c
print 'd = ', d
#输出结果:
a=[1,2,3,4,['a','b','c'],5]
b=[1,2,3,4,['a','b','c'],5]
c=[1,2,3,4,['a','b','c']]
d=[1,2,3,4,['a','b']]
作业
- 用递归函数实现 “ 幂的N次方”
- 写代码判断字符串中的元素是大写还是小写,或者是数字,统计各种元素的个数
- 分别写出字典的item,key ,value 的迭代器,并打印出迭代器中的内容。
加密,闭包,装饰器
加密
- 前后十三为加密
s='World'
jiami=base64.encodestring(s)
print jiami
#结果:V29ybGQ=
jiemi=base64.decodestring(jiami)
print jiemi
#结果:World
s=string.letters
print s
result=raw_input('输入替换字母:')
if result.isupper):
print s[s.index(result) - 13].swapcase()
elif result.islower():
prints[s.index(result) + 13].swapcase()
#结果:
输入替换字母:A
N
- hashlib模块
md=hashlib.md5() #实例化一个md5对象,不能反解
md.update('666666') #要加密的字符串
print md.hexdigest() #获取加密的字符串
#结果:f379eaf3c831b04de153469d1bec345e
hash=hashlib.md5('ABC') #在加密的基础上再加密一层
hash.update('666666')
print hash.hexdigest()
#结果:e60c955dc1534b1cdd13e8eb2c20f722
闭包
闭包就是在你调用一个函数A的时候,函数A给你返回另一个函数B,这个返回的函数就叫闭包
def out(country):
def inner(city):
print '%s,%s'%(country, city)
return inner
F=out('中国')
F('北京')
#结果:中国,北京
装饰器
装饰器:是一个以函数作为参数并返回一个替换函数的可执行函数。
def python():
print 'This is python'
print 'This is program language'
def java():
print 'This is java'
print 'This is program language'
def php():
print 'This is php'
print 'This is program language'
python()
java()
php()
#结果:
This is python
This is program language
This is java
This is program language
This is php
This is program language
以上三个函数有相同的功能,可以把功能封装在一个函数当中。
def python():
print 'This is python'
def java():
print 'This is java'
def php():
print 'This is php'
def dev(func):
func()
print 'This is program language'
dev(python)
dev(php)
#结果:
This is python
This is program language
This is php
This is program language
以上写法如果之前函数名在其他有调用,
开始调用的是python(),而现在调用的是的dev(python),
如果该函数在其他地方有调用,需要逐个去修改。
def python():
print 'This is python'
def java():
print 'This is java'
def out(func):
def inner():
func()
print 'This is program language'
return inner
python = out(python)
python()
#结果:
This is python
This is program language
而在python当中提供了一个语法糖
#注意这个语法糖要写在前面,不然报错
def out(func):
def inner():
func()
print 'This is program language'
return inner
@out
def python():
print 'This is python'
python()
#结果:
This is python
This is program language
给封装的功能添加参数
def out(func):
def inner(text):
func(text)
print 'This is program language'
return inner
@out #python=out(python)
def python(text):
print 'This is %s'%text
python('python')
python('php')
python('java')
作业
- 写一个13位加密、base64组合的加密
- 写一个装饰器
流程控制
运算
算术运算符
# 算术运算符
[1,2,3]*3 #乘法
3-1 =>2 #减
3/2 =>1.5 #商
3//2 =>1 #商取整
5%2 =>1 #余数
2**2 =>4 #2次方
2**5 =>32 #5 次方
赋值运算符
=
+=
*=
/=
//=
%=
**=
比较(关系)运算符
==
!= <> #不等于
<
>
>=
<=
逻辑运算符
and
or
not
#运输优先级
非(not)> 且(and)> 或(or)
成员运算符
in #如果指定的序列中找到指定的值,返回True,否则返回False
not in #如果指定的序列中没有找到指定的值,返回True,否则返回False
身份运算符(比较两个对象的存储单元)
is #判断两个标识是不是引用自同一个对象(id)
is not #判断两个标识是不是引用自不同对象(id)
#例子
a=10
b=10
print id(a)
print id(b)
print a is b
print a is not b
isinstance(a, str) #判断类型是否是 str
isinstance(a,(int,str,float)) #判断是否是元组中任意一种类型
对象的三个特征 id
、value
、type
对应三种判断 is
、==
、isinstance
位运算符(把数字当二进制数进行运算)
& 按位与
| 按位或
^ 按位异或
- 按位取反
<< 左移动
>> 右移动
流程控制(if-elif-else)
代码正常情况下从上到下、从左到右执行
if 判断语句,只有满足if条件的时候才会执行下面的代码块
if 条件:
block
else:
blcok
#例子
num=15
if num==20:
print '==20'
elif num == 10:
print '==10'
else:
print '不满足条件'
循环语句(for、while)
for循环:
for 变量 in 可迭代对象:
block
将后面可迭代对象的元素依次赋值给前面的变量,每赋值一次,执行一次代码块。
嵌套循环:枚举
#例子
for i in range(1,9):
for j in range(1,9):
print j
print '------', i
L=[1,2,3]
for i,j enumerate(L,1):
print i,j
while 循环
while 循环
处理循环任务,在某种条件,循环执行某段代码。
格式:
while 条件: #条件可以是任何表达式,任何非0,非空的值均为True
block
#例子
num=0
while num<10:
if num % 2 == 0:
print num
num += 1
for i in range(1,10):
if i == 5:
break
print i
for i in range(1,10):
if i ==5:
continue
print i
for i in range(1,10):
pass
break
跳出整个循环continue 跳出本次循环
pass
为了保持程序的完整性
作业
题目一:
语文 数学 英语
假使 其中任意 2门课的成绩大于90分,那么成绩为优秀
假使 其中任意 2门课的成绩大于80分,那么成绩为良好
假使 其中任意 2门课的成绩小于80分,那么成绩为差
题目二:
有四个数字:1、2、3、4,能组成多少个互不相同且无重复数字的三位数?各是多少? 程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去 掉不满足条件的排列。
面向对象
面向对象定义
面向过程:根据代码逻辑从上往下码代码
函数式:将某一些功能封装在函数当中,可重复调用
面向对象:对函数进行封装
面向对象的定义:
对象:实实在在存在的一些事物
类的概念
类:对事物的划分,描述一部分事物的共性特征
实例:对事物的具体化
域:就是变量,类或者实例的变量
方法:方法就是函数
属性:对域和方法的统称
类的定义
- 类的编写
- 类的调用(实例化)
- 语法:
class 类名:
def 函数(self):
代码块
self 特殊参数,必须要写
关键字 class
#定义一个类:
class Bird: #类名
hungry =50 #域
def eat(self): #方法
return 'This is eat'
b = Bird() #实例化
print b.hungry #调用实例b的hungry属性
print b.eat() #调用实例b的eat属性
- 类和实例之间,实例和实例之间相互独立
class Bird: #类名
bungry = 50 #域
def eat(self): #方法
return 'This is eat'
print Bird #类本身
a = Bird() #实例
print a
b = Bird()
print b
#结果
__main__.Bird
<__main__.Bird instance at 0x0000000002A92808>
<__main__.Bird instance at 0x0000000003130B08
- self: 实例本身
class Bird: #类名
hungry = 50 #域
def eat(self): #方法
return self
def drink(self):
return self
a = Bird()
print a
print a.eat()
print a.drink()
print '-----------------'
b = Bird()
print b
print b.eat()
print b.drink()
#结果
<__main__.Bird instance at 0x00000000034BEAC8>
<__main__.Bird instance at 0x00000000034BEAC8>
<__main__.Bird instance at 0x00000000034BEAC8>
-----------------
<__main__.Bird instance at 0x00000000034BEB48>
<__main__.Bird instance at 0x00000000034BEB48>
<__main__.Bird instance at 0x00000000034BEB48>
#在继承时,传入的是哪个实例,就是那个传入的实例,而不是指定义了self的类的实例
class Parent:
def pprt(self):
print(self)
class Child(Parent):
def cprt(self):
print(self)
c = Child()
c.cprt()
c.pprt()
p = Parent()
p.pprt()
#结果
<__main__.Child object at 0x0000028F59B02670>
<__main__.Child object at 0x0000028F59B02670>
<__main__.Parent object at 0x0000028F59B02370>
#############
#在描述符类中,self指的是描述符类的实例
class Desc:
def __get__(self, ins, cls):
print('self in Desc: %s' %self)
print(self, ins, cls)
class Test:
x = Desc()
def prt(self):
print('self in Test:%s' %self)
t = Test()
t.prt()
t.x
#结果
self in Test:<__main__.Test object at 0x000002BC67BF9220>
self in Desc:<__main__.Desc object at 0x000002BC67BF9100>
<__main__.Desc object at 0x000002BC67BF9100> <__main__.Test object at 0x000002BC67BF9220> <class '__main__.Test'>
Test.x
#结果
<__main__.Desc object at 0x000002AEFEA79100> None <class '__main__.Test'>
- self在定义时需要定义,调用时会自动传入。
- self的名字并不是规定死的,但是最好还是按照约定用self
- self总是指调用时的类的实例
- 类方法中传递参数
class Obj:
def info(self, name):
print 'This is %s'%name
o = Obj()
o.info('obj')
我们用实例调用实例方法的时候相当于我们用类调用方法并把实例传入
class Bird: #类名
hungry = 50 #域
def eat(self): #方法
print 'This is eat'
def drink(self):
return self
a = Bird()
a.eat()
Bird.eat(a)
面向对象的构造函数和析构函数
构造函数:_init_
- 在类实例化之后自动执行
class Bird:
def __init__(self):
print 'This is __init__'
a = Bird()
- 构造函数传参的时候在实例化的时候传参
class Bird:
def __init__(self, name):
print 'This is __init__,name is %s'%name
a = Bird('json')
- 构造函数是不可以有返回值的
主要用来初始化Python包(packages)的,它在模块加载最开始运行。以下目录结构为示例:
├─test
│ ├─package_1
│ │ ├─__init__.py
│ │ ├─m1.py
│ ├─package_2
│ │ ├─__init__.py
│ │ └─m2.py
│ ├─test.py
其中包含两个包package_1
,package_2
__init__.py
中有什么
如上目录结构,如果两个保重的__init__.py
都为空的话,默认在test.py
中我们只能执行如下:
from package_2 immport m2
pring(m2.m2s())
当想要执行
import package_2
print(package_2.m2.m2s())
或
from package_2 import *
print(m2.m2s())
则会抛出异常AttributeError:module 'package_2' has no attribute 'm2'
这是因为在__init__.py
中并没有进行包提升
如何执行
- 此时以
package_2
包中的__init__.py
为例,当我们在保重提升导入权限即可:
from package_2.m2 import m2s
在test.py
中,执行
from package_2 import m2s
print(m2s())
- 通常我们还会遇到
from xxx import *
,这时我们只需要在__init__.py
中加载all
允许全部导出的模块即可,如在package_2
的__init__.py
中加入:
__alll__ = ['m2']
在test.py
中执行
from package_2 import *
print(m2.m2s())
__all__
是一个列表变量,放的是你希望导入的模块的名字。当__init__.py
中定义了__all__
变量时,import *
只能导入__all__
允许的模块
析构函数:__del__
只有实例完全被删除之后才会执行,一般用于接口关闭,内存回收
class Bird:
def __del__(self):
print 'This is __del__'
a = Bird()
del a
垃圾回收
作业
- 定义一个类(要求有属性,普通方法,构造函数,析构函数),并实例化该类,并用对象取调用类的方法和属性
面向对象的三大特征
封装
封装定义:如果给类当中的一个属性前面加上__之后,导致属性只能在内部调用,外部无法调用
# 通过对象直接调用
class Parent:
def __init__(self, name, age):
self.name = name
self.age = age
p = Parent('json', 18)
print p.name
pring p.age
#通过self间接调用
class Parent:
def __init__(self, name, age):
self.name = name
self.age = age
def Func(self):
print self.age
print self.name
p = Parent('Json', 18)
p.Func()
#私有化
class Parent:
def __Func(self):
print 'This is Func!'
def student(self):
self.__func()
#类当中内部调用
p = Parent()
p.student()
p.__Func() #不可以调用
继承
子类:继承的类是被继承类的子类
父类:被继承的类
class animal:
def eat(self):
print 'This is eat'
def sleep(self):
print 'This is sleep'
class cat(animal):
def drink(self):
print 'This is drink'
class dog(animal):
def drink(self):
print 'This is drink'
d = dog()
d.drink()
d.eat()
c = cat()
c.drink()
c.eat()
#子类对父类的方法或者属性可以重写
class animal:
def eat(self):
print 'This is eat'
def sleep(self):
print 'This is sleep'
class cat(animal):
def eat(self):
print 'This is cat eat!'
class dog(animal):
def drink(self):
print 'This is drink'
c = cat()
c.eat()
#重写之后,如果有同名的属性或者方法,子类覆盖父类
class Parent:
def __init__(self):
self.name = 'json'
self.age = '20'
self.sex = '男'
class subclass(Parent):
def __init__(self):
self.name = 'JSON'
self.age = 18
s = subclass()
print s.name
print s.age
print s.sex #无法调用
#保留父类父类方法的重写
class Parent:
def __init__(self):
self.name ='json'
self.age = '20'
self.sex = '男'
def eat(self):
self.hungry = 50
class subclass(Parent):
def __init__(self):
Parent.__init__(self)
self.name ='JSON'
self.age = 10
def eat(self):
Parent.eat(self)
return self.hungry
s = subclass()
print s.name
print s.age
print s.sex
print s.eat()
多继承
多继承:一个子类可以继承多个父类
如果继承的多个类当中定义了相同的属性或者方法,会优先使用哪个
经典类:没有继承object的类
新式类:继承object的类
深度优先:当类是经典类,会按深度优先方式查找
广度优先:当类是新式类,会按广度优先方式查找
- 类型不一样
class new(object):
pass
class old:
pass
print type(new)
print type(old)
#结果 <type 'type'>
#结果 <type 'classobj'>
- 含有的方法不一样
print dir(new)
print dir(old)
- 继承顺序不一样
#经典类
class A:
num = 1
pass
class B(A):
pass
class C(A):
#num=2
pass
class D(C,B):
pass
d=D()
print d.num
#结果 1
#新式类
class A(object):
num = 1
class B(A):
#num=2
pass
class C(A):
num = 3
class D(B,C):
pass
d = D()
print d.num
print D.__mro__
#结果 3
多态
多态
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”可以这样表述:
· “当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的走和叫方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的走和叫方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。
鸭子类型通常得益于不测试方法和函数中参数的类型,而是依赖文档、清晰的代码和测试来确保正确使用。从静态类型语言转向动态类型语言的用户通常试图添加一些静态的(在运行之前的)类型检查,从而影响了鸭子类型的益处和可伸缩性,并约束了语言的动态特性。
要理解什么是多态,我们首先要对数据类型再作一点说明。当我们定义一个class的时候,我们实际上就定义了一种数据类型。
我们定义的数据类型和Python当中的list ,str ,dict没有什么区别
#判断一个变量是否是某个数据类型: isinstance()
class animal:
def eat(self):
print("This is eat")
def sleep(self):
print("This is sleep")
class cat(animal):
def eat(self):
print("This is cat eat")
class dog(animal):
def drink(self):
print("This is drink")
l=list()
a = animal()
c = cat()
d = dog()
print(isinstance(l, list))
print(isinstance(a, animal))
print(isinstance(c, cat))
print(isinstance(d, dog))
print(isinstance(c, animal))
print(isinstance(d, animal))
#结果
True
True
True
True
True
True
python是一门动态语言,参数在传入之前无法确定参数类型
class A:
def prt(self):
print('A')
class B(A):
def prt(self):
print('B')
class C(A):
pass
class D:
def prt(self):
print('D')
class E:
def hello(self):
pass
def test(args):
args.prt()
a=A()
b=B()
c=C()
d=D()
e=E()
test(a)
test(b)
test(c)
test(d)
#test(e)
print(isinstance(a,A))
print(isinstance(d,A))
#结果
A
B
A
D
True
False
#其中test(e)会报“AttributeError: 'E' object has no attribute 'prt'”错误
作业
- 定义多个类,需要涉及到类的封装,多重继承,并实例化,并调用类的方法和域。
模块,time
模块
模块的概念:
我们把一些同类型的功能收集起来,封装的功能块
导入模块的原理:
- 模块导入会将要导入的文件执行一遍
- 导入模块的名称就是我们定义的脚本或者包的名称
- 我们导入模块过程总结就是:在指定的范围内搜索指定名称对python脚本或者包,将其运行,获取其中的方法
- 导入的范围由sys模块的sys.path方法来规定
导入模块的方式
Import 模块
From 模块 import 功能
From 模块 import *
From 模块 import 功能1,功能2
Import 模块 as 别名
导入关键字 | 导入对象 | 导入后的使用 |
---|---|---|
import | 模块 | 模块,功能 import sys sys.path |
from 模块 import 功能 | 功能 | 功能 from sys import path |
from 模块 import * | 功能 | 功能 这里同样是导入了所有功能 |
from 模块 import 功能,功能 | 功能 | 功能 可以导入多个功能 |
as | 给导入的模块或者功能起别名 |
导入包
导入包:
在python 2版本目录不可以直接被导入,3可以
Python2目录下有__init__.py
文件才可以被导入__init__.py
导入后自动执行
time
模块:
time
时区
UTC 0时区
东八区 上海
时间戳
1970.1.1 0:0:00 距离这个时间过了多少秒
夏令时
0 采用 1不采用 -1 不知道
时间格式:
-
字符串时间
-
九元素时间
-
年 tm_year
-
月 tm_mon
-
日 tm_mday
-
时 tm_hour
-
分 tm_min
-
秒 tm_sec 1-61
-
一周的第几天 tm_wday 0-6
-
一年的第几天 tm_yday
-
是否夏令时 tm_isdst 1 启用 0 不启用 -1不知道
-
模块TIME的函数
函数名称 | 作用说明 |
---|---|
time.localtime | 返回当前时区的九元素时间 |
time.gmtime | 返回0时区的九元素时间 |
time.struct_time | 将一个九元素元组转换成时间 |
time.asctime | 将九元素时间转换成字符串格式 周 月 日 时 分 秒 年 |
time.ctime | 将时间戳转换为字符串时间 周 月 日 时 分 秒 年 |
time.strftime | 定制指定格式字符串时间 |
time.strptime | 函数根据指定的格式把一个时间字符串解析为时间元组 |
time.time | 返回当前时间的时间戳 |
time.mktime | 返回九元素时间的时间戳 |
time.clock | 在Linux系统上,它返回的是”进程时间”,它是用秒表示的浮点数(时间戳)。而在WINDOWS中,第一次调用,返回的是进程运行的实际时间。而第二次之后的调用是自第一次调用以后到现在的运行时间 |
time.sleep | 就是让程序挂起指定秒 |
九元素时间
Strftime 的格式符
%y 两位
%Y 四位
%m 月
%d 日
%H 24时
%l 12小时
%M 分
%S 秒
模块DATETIME
date
日期类,属性:year,month,day
Year范围[1,9999]
Month范围[1,12]
Day最大值根据year和month参数来决定
Date.max
显示年、月、日的最大值
Date.min
显示年、月、日的最小值
Date.resolution
日期的最小单位,(天)
Date.today()
返回当前日期
Date.replace()
生成一个新的时间,用参数指定的年月日代替原有的年月日
Date.timetuple()
返回日期对应的九元素时间
Date.weekday()
返回weekday,周一从1开始
Date.isoweekday()
返回weekday,周一从0开始
Date.isocalendar()
返回一个元组(年,月,日)
Date.isoformat()
返回一个字符串时间 年-月-日
Date.strftime()
自定义格式化字符串
Time
时间类 属性:hour,minute,second,microsecond(微妙)
Time.replace()
生成一个新的时间,用参数指定的时分秒代替原有的时分秒
Time.isoformat()
返回一个字符串时间 HH:MM:SS
Time.strftime()
自定义格式化字符串
编辑母版文本样式
作业
- 编写一个模块A,并在另一个模块B导入模块A并调用A的函数
文件操作
打开文件
打开文件:
open(file, mode=‘r’) #file:要打开的文件路径 ,mode:权限
f = open(r'C:\Users\XueGod\Desktop\1.txt','r')
‘r’ open for reading (default)
以只读模式打开文件,这个是默认的
‘w’ open for writing, truncating the file first
以只写模式打开文件,并且每次以该模式打开文件都会首先将文件截断
‘x’ create a new file and open it for writing
创建一个新文件,并且以只写模式打开,如果文件已经存在,FileExistsError
‘a’ open for writing, appending to the end of the file if it exists
以写模式打开文件,如果文件存在接下来做的读写操作都在文件末尾进行,如果文件不存在则创建文件
‘t’ text mode (default)
以文本文件模式打开文件,这个也是默认的
‘+’ open a disk file for updating (reading and writing)
a+: 读写模式打开,之后所做的读写操作都将从文件末尾开始
w+: 读写模式打开,文件存在则将文件内容截断为0,文件不存在则创建文件
r+: 读写模式打开文件,只能在文件存在时这样做,文件不存在,出现
(FileNotFoundError: [Errno 2] No such file or directory: 'file.name’)
读文件
f = open(r'C:\Users\XueGod\Desktop\1.txt','r')
Str=f.read(num)
// 读取文件放到字符串变量中 其中的num 就是要读取的字节数 不填为全读Str=f.readline()
//读取文件中的一行字符串保存到变量中List=f.readlines()
//读取文件中的所有内容保存到列表中
f = open(r'C:\Users\XueGod\Desktop\1.txt','r')
f.read()
f.read(3)
#与
f = open(r'C:\Users\XueGod\Desktop\1.txt','r')
f.read(3)
#结果不一样
文件指针的位置和移动
file.seek(offset[,whence])
file.seek(0,0) #将文件把操作标记移到offset的位置
#这个offset一般是相对于文件的开头来计算的,一般为正
whence可以为
0表示从头开始偏移
1表示以当前位置为原点偏移
2表示以文件末尾为原点进行偏移
file.tell()
用来显示你现在文件读写指针的位置
写文件
f=open(r'C:\Users\XueGod\Desktop\1.txt', 'w/a/w+/a+/r+')
f.write('str') #将字符串写入到文件中
f.writelines(list_of_string) #将列表中的字符串写入到文件中
f.flush() #将输入的内容从内存中刷新到磁盘的文件中
#键盘输入的内容,先写入到缓冲区,再刷新到磁盘上的文件
关闭文件
f=open(r'C:\Users\XueGod\Desktop\1.txt', 'w')
f.close() #关闭文件,有打开文件就有关闭文件
练习
使用本地文件当作数据库,实现用户登录、注册的功能:
要求:str='%s:%s'%s(str1,str2) //把2个字符串以“:”的方式连接;
* 需要用到的 split() 函数,str.split(str="", num=string.count(str))[n]
str1=str.split(':')[0]
str2=str.split(':')[1]
* 文件保存密码账号,一定格式 account:password
注册用户编辑思路:
1. 先手动创建一个空白的TXT文件
2. 以A模式打开
3. 通过INPUT()来获取输入的用户名和密码
4. 通过str="%s:%s"%s(str1,str2) //把2个字符串以:的方式连接
5. 把STR写入到TXT文件中
6. 关闭文件
登录验证编写思路:
1. 以只读的方式打开我们前面往里头写入用户名和密码的TXT文档
2. 让用户输入用户名和密码
3. 循环读取文件中的每一行字符串
4. 通过 split() 函数把字符串以':'方式拆分成2个小字符串
5. 对比用户输入的用户名是否等于拆分后的小字符串1, 密码是否等于拆分后的小字符串2;若都相等,则提示登录成功,反之提示登录失败
6. 关闭文件
os.path
模块功能
方法 | 功能 |
---|---|
os.path.abspath(path) | 返回绝对路径 |
os.path.split(path) | 将path分割成目录和文件名二元组返回 |
os.path.dirname(path) | 返回path的目录。其实就是os.path.split(path)的第一个元素 |
os.path.basename(path) | 返回path最后的文件名 |
os.path.exists(path) | 如果path存在,返回True;如果path不存在,返回False |
os.path.isabs(path) | 如果path是绝对路径,返回True |
os.path.isfile(path) | 如果path是一个存在的文件,返回True。否则返回False |
os.path.isdir(path) | 如果path是一个存在的目录,则返回True。否则返回False |
os.path.getatime(path) | )返回path所指向的文件或者目录的最后存取时间 |
os.path.getmtime(path) | 返回path所指向的文件或者目录的最后修改时间 |
os.path.getctime(path) | 返回path所指向的文件或者目录的创建时间 |
os.path.getsize(name) | 获得文件大小,如果name是目录返回0L |
os.path.join(path1[, path2[, …]]) | 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略. |
os.path.splitext() | 分离文件名与扩展名 |
socket编程
何为socket
SOCKET协议
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的
TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
通讯方式
单工通讯:只有一条通讯链路,且通讯线角色是固定的,类似BB机
半双工通讯:只有一条通讯链路,但是通讯角色是可以互换的,但某一时刻,只允许数据在一个方向上传输,类似微信对讲机
全双工通讯:有多条通讯链路,且通讯角色是可以互换的。
Windows Socket —-SOCKET与TCP/IP的关系图
Windows Socket —-Socket工作原理
SOCKET函数
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
参数一:地址簇
socket.AF_INET IPv4(默认)
socket.AF_INET6 IPv6
socket.AF_UNIX 只能够用于单一的Unix系统进程间通信
参数二:类型
socket.SOCK_STREAM 流式socket , for TCP (默认)
socket.SOCK_DGRAM 数据报式socket , for UDP
参数三:协议
0 (默认)与特定的地址家族相关的协议,如果是 0 ,
则系统就会根据地址格式和套接类别,自动选择一个合适的协议
sock.bind(address)
s.bind(address) 将套接字绑定到地址。address地址的格式取决于地址族。
在AF_INET下,以元组(host,port)的形式表示地址。
比如:sock.bind((“192.168.3.101”,8080))
ip : 绑定自己的Ip, 若是为空,则代表所有
端口:0-65535, 一般前1000不用 ,80
sock.listen(backlog)
开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。
Con,(ip,port)=sock.accept()
Sock.accept()接受连接并返回2个值
第一个值con 用来发送和接收数据的
第二值(ip,port)是一个元组,表示链接人的ip和端口
该元组的元素一:ip
元素二:port
sock.connect(address)
连接到address处的套接字。一般,address的格式为元组(hostname,port),
比如sock.connect((“192.168.3.101”,8080))
sock.send(string[,flag])
将string中的数据发送到连接的套接字。
比如:sock.send(input(“>>>”).encode()) (python 3.x)
sock.send(raw_input(“>>>”)) (python 2.7)
sock.recv(bufsize[,flag])
接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。
比如: sock.recv(512).decode() (python 3.x)
sock.recv(512) (python 2.7)
sock.close()
关闭套接字
用socket发送实时信息
用socket 发送文件
Socket 发送文件的思路
先发送文件的信息, 比如文件名,文件大小
再发送文件的内容,比如每次传512个字节,直至传完
传文件内容的流程:发送端是读文件并发送数据的过程,
接收端是接收数据并写文件的过程。
python os.path,os.stat, os.struct模块
os.path.isfile(path) #判断路径是否为文件
os.path.basename(path) #返回文件名
os.stat(path).st_size #获取文件的大小>>> print os.stat("/root/python/zip.py").st_size #文件的大小,以位为单位 864
struct.calcsize
struct.calcsize用于计算格式字符串所对应的结果的长度,如:struct.calcsize(‘ii’),返回8。因为两个int类型所占用的长度是8个字节
struct.pack
struct.pack用于将Python的值根据格式符,转换为字符串(因为Python中没有字节(Byte)类型,可以把这里的字符串理解为字节流,或字节数组)。其函数原型为:struct.pack(fmt, v1, v2, …)
struct.unpack
struct.unpack做的工作刚好与struct.pack相反,用于将字节流转换成python数据类型。它的函数原型为:struct.unpack(fmt, string),该函数返回一个元组。
http://www.cnblogs.com/dkblog/archive/2011/03/25/1995537.html pathhttp://www.cnblogs.com/maseng/p/3386140.html stathttp://blog.csdn.net/occupy8/article/details/11052103 struct
多个server 端,其中有ManagerServer
思路:
- 所有的Agent 都先连ManagerServer , 并发送文件名给ManagerServer;
- ManagerServer 根据文件类型的不同返回发送不同的ip,port 给agent
- Agent 根据接收到ip,port 去创建新的socket 去连新的Server
- 创建链接后,发送文件
- 关闭socket
测试
测试金字塔模型中分为三层:最底层是单元测试,中间层接口测试,最顶层UI测试
单元测试框架:unittest(python自带的)、nose和nose2、pytest(推荐)
#启动app的压力测试(unittest)
from time import sleep
import os
def test_startUpApp(AppName,AppPackage):
#启动app
StartUpApp = os.popen(AppName)
sleep(3)
#停止app
KillApp = os.popen(AppPackage)
sleep(2)
#使用for循环启动、关闭app----100次
for i in range(1,101):
AppName = "adb shell am start -n com.zhongdamen.zdm/com.zhongdamen.zdm.view.login.WelcomeActivity"
AppPackage = "adb shell am force-stop com.zhongdamen.zdm"
test_startUpApp(AppName,AppPackage)
print("第{}次启动app".format(i))
接口测试
https://juejin.im/post/5d1f355cf265da1bd2610c75
例子
心愿打印机
(纯粹输出)
//main.py
print('曾经有一段真挚的爱情摆在我眼前,')
print('我没有去珍惜等到失去了才后悔莫及。')
print('尘世间最痛苦的事莫过于此,')
print('如果上天能给我一个再来一次的机会,')
print('我希望能对那个女孩说我爱你,')
print('如果非要给这份爱加一个期限的话,')
print('我希望是一万年。')
print('')
print(' ***** *****')
print(' ******* *******')
print(' ******************')
print(' ****************')
print(' ************')
print(' ********')
print(' **')
猜数字小游戏
(弹窗输入数字与结果比对)
//main.py
num = 414//23
number = input('猜一猜414//23的运行结果吧')
times = 1
while True:
if times > 2:
break
if number.isnumeric():
if int(number) == num:
break
if int(number) > num:
number = input('不对哦,猜大了')
else:
number = input('不对哦,猜小了')
else:
number = input('需要在下方输入数字')
times += 1
if times > 2 and int(number) != num:
print('三次机会用完了')
else:
print('恭喜你猜中了')
print('结果是' + str(num))
武汉加油
(红色实心+武汉加油文字)
//main.py
import turtle
def curvemove():
for i in range(200):
turtle.right(1)
turtle.forward(1)
turtle.color('red')
turtle.begin_fill()
turtle.left(140)
turtle.forward(111.65)
curvemove()
turtle.left(120)
curvemove()
turtle.forward(111.65)
turtle.end_fill()
turtle.penup()
turtle.goto(-40, -50)
turtle.pendown()
turtle.write('武汉加油', font = ('SimHei', 15, 'bold'))
turtle.hideturtle()
绘制圣诞树
(绘制圆形+矩形,不同位置排出圣诞树形状)
//main.py
import turtle
screen = turtle.Screen()
screen.setup(375,700)
circle = turtle.Turtle()
circle.shape('circle')
circle.color('red')
circle.speed('fastest')
circle.up()
square = turtle.Turtle()
square.shape('square')
square.color('green')
square.speed('fastest')
square.up()
circle.goto(0,280)
circle.stamp()
k = 0
for i in range(1, 13):
y = 30*i
for j in range(i-k):
x = 30*j
square.goto(x,-y+280)
square.stamp()
square.goto(-x,-y+280)
square.stamp()
if i % 4 == 0:
x = 30*(j+1)
circle.color('red')
circle.goto(-x,-y+280)
circle.stamp()
circle.goto(x,-y+280)
circle.stamp()
k += 3
if i % 4 == 3:
x = 30*(j+1)
circle.color('yellow')
circle.goto(-x,-y+280)
circle.stamp()
circle.goto(x,-y+280)
circle.stamp()
square.color('brown')
for i in range(13,17):
y = 30*i
for j in range(2):
x = 30*j
square.goto(x,-y+280)
square.stamp()
square.goto(-x,-y+280)
square.stamp()
text = turtle.Turtle()
text.hideturtle()
text.penup()
text.goto(-120, 270)
text.color('red')
text.write('圣诞快乐', font = ('SimHei', 18, 'bold'))
#可以把【圣诞快乐】换成你的祝福语哦~
拯救小哪吒
(迷宫+控制移动)
//main.py
from maze import Maze
from nezha import Nezha
from controller import Controller
maze_list = [
[1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1],
[1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1],
[1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1]
]
Maze(maze_list)
nezha = Nezha(maze_list, 0, 5, 12, 7)
Controller(nezha.go_up, nezha.go_down, nezha.go_left, nezha.go_right)
//maze.py
from turtle import Turtle
class Maze(Turtle):
size = 20
def __init__(self, maze_list):
# 需要先调用父类的初始化方法才能在初始化方法中调用父类的方法
Turtle.__init__(self)
self.maze_list = maze_list
# 为了加快绘图速度隐藏海龟,速度设为最快
self.hideturtle()
self.speed(0)
self.draw_walls()
def draw_wall(self):
self.pendown()
self.begin_fill()
self.fillcolor('#7392f6')
for i in range(4):
self.forward(self.size)
self.right(90)
self.end_fill()
self.penup()
def draw_walls(self):
self.penup()
# 从 (-130, 130) 开始
self.goto(-130, 130)
for row in range(13):
for col in range(13):
if self.maze_list[row][col] == 1:
self.draw_wall()
# 右移一列
self.goto(self.size * (col + 1) - 130, 130 - self.size * row)
# 下移一行
self.goto(-130, 130 - self.size * (row + 1))
//nezha.py
from turtle import Turtle
class Nezha(Turtle):
def __init__(self, maze_list, start_m, start_n, end_m, end_n):
# 父类初始化
Turtle.__init__(self)
self.m = start_m
self.n = start_n
self.end_m = end_m
self.end_n = end_n
self.maze_list = maze_list
self.hideturtle()
self.speed(0)
self.penup()
# 移到对应的位置
self.goto(self.n * 20 - 120, 120 - self.m * 20)
# 变成海龟
self.shape('turtle')
self.color('#28bea0')
self.setheading(270)
self.showturtle()
# 添加哪吒图片作为形状
screen = self.getscreen()
screen.addshape('nezha.png')
def reach_exit(self, m, n):
if m == self.end_m and n == self.end_n:
# 变成哪吒
self.shape('nezha.png')
def canmove(self, m, n):
return self.maze_list[m][n] == 0
def move(self, m, n):
self.m = m
self.n = n
self.goto(self.n * 20 - 120, 120 - self.m * 20)
self.reach_exit(m, n)
def go_up(self):
if self.canmove(self.m - 1, self.n):
self.setheading(90)
self.move(self.m - 1, self.n)
def go_down(self):
if self.canmove(self.m + 1, self.n):
self.setheading(270)
self.move(self.m + 1, self.n)
def go_left(self):
if self.canmove(self.m, self.n - 1):
self.setheading(180)
self.move(self.m, self.n - 1)
def go_right(self):
if self.canmove(self.m, self.n + 1):
self.setheading(0)
self.move(self.m, self.n + 1)
//controller.py
from turtle import Turtle
class Controller(Turtle):
def __init__(self, go_up, go_down, go_left, go_right):
# 父类初始化
Turtle.__init__(self)
# 初始值设置
self.go_up = go_up
self.go_down = go_down
self.go_left = go_left
self.go_right = go_right
# 绘制控制器
self.hideturtle()
self.speed(0)
self.draw_btn('上', -15, 165)
self.draw_btn('下', -15, -135)
self.draw_btn('左', -165, 15)
self.draw_btn('右', 135, 15)
# 绑定点击事件
screen = self.getscreen()
screen.onclick(self.handlescreenclick)
def draw_btn(self, name, x, y):
self.penup()
self.goto(x, y)
self.begin_fill()
self.fillcolor('#ffffff')
for i in range(4):
self.forward(30)
self.right(90)
self.end_fill()
self.color('#000000')
self.goto(x + 7, y - 20)
self.write(name, font = ('SimHei', 12, 'bold'))
def handlescreenclick(self, x, y):
if y > 0 and abs(x) < y:
self.go_up()
if y < 0 and abs(x) < -y:
self.go_down()
if x < 0 and abs(y) < -x:
self.go_left()
if x > 0 and abs(y) < x:
self.go_right()