python
- microsoft/c9-python-getting-started: Sample code for Channel 9 Python for Beginners course
https://github.com/microsoft/c9-python-getting-started - “Windows 上的 Python”文档 | Microsoft Docs
https://docs.microsoft.com/zh-cn/windows/python/ - selfteaching/the-craft-of-selfteaching: One has no future if one couldn't teach themself.
https://github.com/selfteaching/the-craft-of-selfteaching - Python教程 - 廖雪峰的官方网站
https://www.liaoxuefeng.com/wiki/1016959663602400 - 利用 Python 进行多 Sheet 表合并、多工作簿合并、一表按列拆分
https://mp.weixin.qq.com/s/R9zp3nJOjSCYlazUQ9lyAA - [小甲鱼]零基础入门学习Python_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili
https://www.bilibili.com/video/av4050443?p=1 - 3.8.2rc2 Documentation
https://docs.python.org/zh-cn/3/index.html - Python3 教程 | 菜鸟教程
https://www.runoob.com/python3/python3-tutorial.html - Python 基础教程 | 菜鸟教程
https://www.runoob.com/python/python-tutorial.html - 1小时入门Python
https://python.freelycode.com/train/start0
阎王生死簿系统
Docker Hub
https://hub.docker.com/_/python
学习记录点
https://www.bilibili.com/video/av4050443?p=9
我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。
python 安装
百度谷歌一下吧,linux 自带
apt-install python
python 简介
python 是一门现代,流行,好用的脚本编程语言。
python之禅
在idle
输入
import this
会显示
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.
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 代码文件标准开头
#!/usr/bin/python
# -*- coding: utf-8 -*-
print("hello world")
python3
#!/usr/bin/python3
# -*- coding: utf-8 -*-
print("hello world")
Python namespace
Python有几个namespace,分别是
- locals
- globals
- builtin
其中定义在函数内声明的变量属于locals,而模块内定义的函数属于globals。
Python module Import & Name Lookup
当我们import一个module时,python会做以下几件事情
- 导入一个module
- 将module对象加入到sys.modules,后续对该module的导入将直接从该dict中获得
- 将module对象加入到globals dict中
当我们引用一个模块时,将会从globals中查找。这里如果要替换掉一个标准模块,我们得做以下两件事情
- 将我们自己的module加入到sys.modules中,替换掉原有的模块。如果被替换模块还没加载,那么我们得先对其进行加载,否则第一次加载时,还会加载标准模块。(这里有一个import hook可以用,不过这需要我们自己实现该hook,可能也可以使用该方法hook module import)
- 如果被替换模块引用了其他模块,那么我们也需要进行替换,但是这里我们可以修改globals dict,将我们的module加入到globals以hook这些被引用的模块。
monkey patch (猴子补丁)
https://www.cnblogs.com/youxin/p/3805706.html
monkey patch用来在运行时动态修改已有的代码,而不需要修改原始代码。
这个叫法起源于Zope框架,大家在修正Zope的Bug的时候经常在程序后面追加更新部分,这些被称作是“杂牌军补丁(guerilla patch)”,后来guerilla就渐渐的写成了gorllia((猩猩),再后来就写了monkey(猴子),所以猴子补丁的叫法是这么莫名其妙的得来的。
还有一种解释是说由于这种方式将原来的代码弄乱了(messing with it),在英文里叫monkeying about(顽皮的),所以叫做Monkey Patch。
示例
#[python3.x] monkey patch 的简单实现
#coding=utf-8
def originalFunc():
print('this is original function!')
def modifiedFunc():
modifiedFunc=1#这里不会影响
print(modifiedFunc)
print('this is modified function!')
def main():
originalFunc()
originalFunc()
modifiedFunc()
modifiedFunc()
if __name__=='__main__':
originalFunc=modifiedFunc
main()
python中的规则
-
python中所有的东西都是object,包括基本类型。查看一个object的所有属性的方法是:dir(obj)
-
函数在python中可以像使用变量一样对它进行赋值等操作。
-
查看属性的方法:
locals()
和globals()
。
tuple(元组)
元组和列表十分类似,只不过元组和字符串一样是不可变的,即你不能修改元组。元组通过圆括号中用逗号分割的项目定义。元组通常用在使语句或用户定义的函数能够安全地采用一组值的时候,即被使用的元组的值不会改变。
注意:定义元组的是逗号,而非括号。
如下所示
tuple1=1,"bee",True,None
tuple2=(1,"bee",True,None)
type(tuple1)#<class 'tuple'>
type(tuple2)#<class 'tuple'>
tuple3=(1,2,3),"Green",(True,False),None
type(tuple3[0])#<class 'tuple'>
python 版本
目前有两个版本 2.7 和 3.x,两者不能兼容。
python 和 pip 安装
python下载地址:https://www.python.org/downloads/
pip下载地址:https://pypi.python.org/pypi/pip#downloads
python装好后,记得加path环境变量
pip是包管理器,pip 安装一般有两个版本
pip-1.5.6-py2.py3-none-any.whl
pip-1.5.6.tar.gz
选下面一个即可
进入目录执行
python setup.py install
然后找到python安装路径下面的scripts文件夹路径添加到path,里面有pip,路径类似于
C:\Python34\Scripts
安装测试
pip install tornado
pip3 install tornado
pip换源
常见的国内源
pip国内的一些镜像
- 阿里云 http://mirrors.aliyun.com/pypi/simple/
- 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/
- 豆瓣(douban) http://pypi.douban.com/simple/
- 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/
- 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
win+R 打开用户目录%HOMEPATH%
,在此目录下创建 pip 文件夹,在 pip 目录下创建 pip.ini 文件, 内容如下
[global]
timeout = 6000
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn
上面使用的清华的镜像源
Linux下更换镜像源
修改 ~/.pip/pip.conf
文件, 没有则创建
[global]
timeout = 6000
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn
python web server
python 2.x
在项目根目录执行,即开启一个简单的web service
python -m SimpleHTTPServer 8080
python2 -m SimpleHTTPServer 8080
默认打开index.html
如果没有,支持目录浏览。
python 3.x
python -m http.server 8080
python3 -m http.server 8080
python QA
1.如何查看一个object的所有属性的方法?
python中所有的东西都是object,包括基本类型。查看一个object的所有属性的方法是:dir(str)
。
2. py脚本中#!/usr/bin/python3的作用?
脚本语言的第一行,目的就是指出,你想要你的这个文件中的代码用什么可执行程序去运行它
#!/usr/bin/python
是告诉操作系统执行这个脚本的时候,调用/usr/bin下的python解释器。
#!/usr/bin/env python
这种用法是为了防止操作系统用户没有将python装在默认的/usr/bin
路径里。
当系统看到这一行的时候,首先会到env设置里查找python的安装路径,再调用对应路径下的解释器程序完成操作。这种写法会去环境设置寻找python目录,推荐这种写法
3.怎么判断传入的路径是文件还是文件夹?
https://blog.csdn.net/ZenG_xiangt/article/details/81869177
import os
if os.path.isdir(path):
print "it's a directory"
elif os.path.isfile(path):
print "it's a normal file"
else:
print "it's a special file(socket,FIFO,device file)"
4.怎么判断文件或文件夹是否存在?
https://www.cnblogs.com/jhao/p/7243043.html
import os
os.path.exists(test_file.txt)
#True
os.path.exists(no_exist_file.txt)
#False
import os
os.path.exists(test_dir)
#True
os.path.exists(no_exist_dir)
#False
import os
os.path.isfile("test-data")
5.同时装了Python3和Python2,怎么用pip
同时装了Python3和Python2,怎么用pip? - 知乎
https://www.zhihu.com/question/21653286
我们在安装Python3(>=3.3)时,Python的安装包实际上在系统中安装了一个启动器py.exe,默认放置在文件夹C:\Windows\下面。这个启动器允许我们指定使用Python2还是Python3来运行代码(当然前提是你已经成功安装了Python2和Python3)。
# 通过 参数指定版本
py -2 hello.py
py -3 hello.py
# 通过文件头指定版本
#! python2
#! python3
# 通过参数指定pip
py -2 -m pip install XXXX
py -3 -m pip install XXXX
# 文件头版本和编码顺序
#! python2
# coding: utf-8
- https://www.anaconda.com/
- https://docs.anaconda.com/anaconda/install/
- the-craft-of-selfteaching/T-appendix.jupyter-installation-and-setup.ipynb at master · selfteaching/the-craft-of-selfteaching
https://github.com/selfteaching/the-craft-of-selfteaching/blob/master/T-appendix.jupyter-installation-and-setup.ipynb - anaconda individual edition简介-成长日志-51CTO博客
https://blog.51cto.com/taoismli/2498684
jupyter
https://github.com/jupyterlab/jupyterlab/blob/master/docs/source/user/code_console.rst
https://github.com/jupyterlab/jupyterlab
web2py
Web2py生死簿管理系统_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili
https://www.bilibili.com/video/BV164411u7yC?p=2
Third part
加一行注释,让你的 Python 程序提速 10+ 倍!Numba 十分钟上手指南
https://mp.weixin.qq.com/s/14mItB_75rOAb2a_4AGdPA
pygame
https://www.cnblogs.com/wuzhanpeng/p/4264267.html
Python 之 pip安装 及 使用详解 - 原点 - CSDN博客
https://blog.csdn.net/ZCShouCSDN/article/details/85002647
python snippet
验证码文字生成
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import random
def genValidateCode(length=6):
'''
生成验证码,
length 验证码长度,默认 6
'''
# 去除 数字0 1 小写字母 i l o 大写字母 I O 这些字符容易混淆
text = "23456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ";
code = "";
for i in range(0,length):
index = random.randint(0,len(text)-1);#不包含长度最大值
c = text[index];
code += c;
pass
return code;
pass
code =genValidateCode()
print(code)
输出字母A-Z
- A: 65
- Z: 90
- a: 97
- z: 122
#!/usr/bin/python3
# -*- coding: utf-8 -*-
def printAtoZ(isSmall=False):
'''
输出大写字母A-Z
'''
result=""
start=65
end=90
if isSmall:
start=97
end=122
pass
for i in range(start,end+1):
result+=chr(i)+" "
pass
result=result[0:-1]
print(result)
pass
printAtoZ()
printAtoZ(True)
输出文本的字符编码
#!/usr/bin/python3
# -*- coding: utf-8 -*-
def printCharCode(text):
'''
输出文本对应的编码值
'''
# 参数检查-类型判断
if not isinstance(text, (str)):
raise TypeError('the arg [text] type need string type')
result=""
for i in range(0,len(text)):
result+=str(ord(text[i]))+","
pass
result=result[0:-1]
print(result)
pass
printCharCode("重庆市长寿区")
使用for输出1到15数字
def print1To10():
for i in range(0,11):
print('Line:%s' % i)
pass
pass
斐波那契函数
# -*- coding: utf-8 -*-
def fibonacci_number(n):
'''
斐波那契函数
'''
a, b = 0, 1
for i in range(0, n):
a, b = b, a + b
yield a
pass
for num in fibonacci_number(15):
print(num)
阶乘函数(递归函数的经典例子)
递归调用的次数过多,会导致栈溢出。可以试试fact(1000)
# 会爆栈
def fact(n):
if n == 1:
return 1
return n * fact(n - 1)
pass
# 循环写法,不会爆栈
def fact2(n):
if n == 1:
return 1
sum= 1
for i in range(n,0,-1):
sum *=i
return sum
pass
# 尾调用方式,可惜py编译器没有实现尾调用优化,还是会爆栈
def fact3(n):
return fact_iter(n, 1)
def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num - 1, num * product)
去除空白字符的函数(trim)
def trim(s):
while s[:1] == ' ':
s = s[1:]
while s[-1:] == ' ':
s = s[:-1]
return s
找最小值和最大值
# -*- coding: utf-8 -*-
def findMinAndMax(L):
if len(L) == 0:
return (None, None)
max = L[0]
min = L[0]
for item in L:
if item > max:
max = item
if item < min:
min = item
return (min,max)
杨辉三角
# -*- coding: utf-8 -*-
def triangles():
L = [1]
while True:
yield L
L = [1]+[L[i]+L[i+1] for i in range(len(L)-1)]+[1]
pass
n = 0
results = []
for t in triangles():
results.append(t)
n = n + 1
if n == 10:
break
for t in results:
print(t)
if results == [
[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1],
[1, 5, 10, 10, 5, 1],
[1, 6, 15, 20, 15, 6, 1],
[1, 7, 21, 35, 35, 21, 7, 1],
[1, 8, 28, 56, 70, 56, 28, 8, 1],
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
]:
print('测试通过!')
else:
print('测试失败!')
8 water
每天8杯水
import os
import time
water_data_path=os.path.join(os.path.abspath('.'),"8water.data")
water_log_path=os.path.join(os.path.abspath('.'),"8water.log")
count = 0
time2=time
def check_file_exist():
if not os.path.isfile(water_data_path):
with open(water_data_path,'w',encoding='utf-8') as file:
file.write(str(count)+"\n")
file.write(time.strftime("%Y-%m-%d 00:00:00", time.localtime()))
if not os.path.isfile(water_log_path):
with open(water_log_path,'w',encoding='utf-8') as file :
file.writelines("")
pass
def update_data():
global count,time2
with open(water_data_path,'r',encoding='utf-8') as file:
count = int(file.readline())
time2 = time.strptime(file.readline(),"%Y-%m-%d %H:%M:%S")
with open(water_data_path,'w',encoding='utf-8') as file:
if time.mktime(time.localtime()) - time.mktime(time2) >= 86400 :
count = 0
pass
count = count + 1
file.write(str(count)+"\n")
file.write(time.strftime("%Y-%m-%d 00:00:00", time.localtime()))
pass
def write_log():
global count,time2
with open(water_log_path,'a',encoding='utf-8') as file:
time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
file.writelines(time_str + ":您喝了第 "+ str(count) +" 杯水\n")
if count == 8:
file.writelines(time_str+":恭喜您完成了一天喝 8 杯水的挑战! ^.^\n")
pass
if time.mktime(time.localtime()) - time.mktime(time2) >= 86400 and count < 8:
file.writelines(time_str+":您之前没有坚持每天喝八杯水哦,请加油\n")
pass
pass
if __name__=='__main__':
check_file_exist()
update_data()
write_log()
cpython record
目录
- 自学是门手艺-李笑来
- 练习用代码片段参考
3.8.2rc2 Documentation
https://docs.python.org/zh-cn/3/index.html
记录 python的各个详细的部分内容,以下内容均以 python3 为准,当下面的文档和官方文档差不多的时候,我也学的差不多了
[TOC]
Python的代码缩进风格
通过缩进代替在其他语言中的花括号,如javascript里面
function helloWorld(){
console.log('hello world');
}
helloWorld();
Python:
def helloWorld():
print("hello world")
helloWorld()
print() 函数
基础的文本输出
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# hello world
print("hello, world")
# 变量
text = "hello, world"
print(text)
# 输出3遍
text = "hello, world"
print(text*3)
# 换行输出3遍
text = "hello, world\n"
print(text*3)
# 跨行输出
print('''今天
天气
真好''')
print("""今天
天气
真好""")
str="aa"+\
"bb"+\
"cc"
print(str)
sum = 1 +\
2 +\
3
print(sum)
print('The quick brown fox', 'jumps over', 'the lazy dog')
print('\u4e2d\u6587')
一行代码多行分隔
sum = 1 +\
2 +\
3
print(sum)
# error
sum = 1 +
2 +
3
print(sum)
基础数据类型
类型 | 说明 |
---|---|
string | 文本类型 |
number | 数字类型 |
object | 对象类型 |
tuple | 元祖类型 |
bool | bool类型 ,非零为真,0:false,1:true |
布尔逻辑处理 Boolean
乔治 布尔的书籍:
- An Investigation of the Laws of Thought by George Boole
- The Mathematical Analysis of Logic by George Boole
Boolean,和C语言一样,非零为真,同时bool类型可看作 0 和 1,注意 python 中的 True 和 False 首字母大写
True:1
False:0
print(int(True))#1
print(int(False))#0
逻辑操作符
>
>
>=
<=
==
!=
in
布尔运算操作符
与 或 非
- and 交集
- 左交集
- 右交集
- or 并集
- not 取反
and
or
not
流程控制语句 Control Flow
顺序语句 Sequence
a=1
b=3
sum = a+b
sumStr=str(sum)
print("sum:"+sumStr)#4
条件分支语句 Case
有如下几种
- if 语句
- if /else 语句
- if/elif(else if)/else 语句
if
numA=7
if numA >5:
print("numA bigger than 5")
if/else
numB=3
if numB > 5:
print("numB bigger than 5")
else:
print("numB smaller than 5")
if/elif/else
numC=5
if numC > 5:
print("numC bigger than 5")
elif numC ==5:
print("numC equall to 5")
else:
print("numC smaller than 5")
循环语句 Loop
有如下几种
- while 循环 Condition-controlled loops(以条件为基础的循环)
- for循环 Collection-controlled loops(以集合为基础的循环)
while 循环
count =5
while count >0:
print("hi,boy")
count = count-1
print("count:"+str(count))
for循环
def print1To10():
for i in range(0,11):
print('Line:%s' % i)
pass
pass
文本处理
- ord()
- chr()
文本拼接
使用 + 号 ,注意和数字运算的 + 不同,转换文本的 bif 为 str()
str(95)+str(27)
"5"+"8" //58
‘5’+‘8’ // 58
'hi'+' , '+'tom'//hi , tom
文本换行
- Python 的非正式介绍 — Python 3.8.2rc2 文档
https://docs.python.org/zh-cn/3/tutorial/introduction.html#strings
和 C语言一样,使用 \n
转义符表示换行,\t
表示制表形式分隔,常用只有这两个,其他参考文档
print("aaa\tbbb")
# aaa bbb
print("aaa\nbbbb")
#aaa
#bbb
避免转移,使用原始文本
通常用于windows上的文件路径
print("c:\\windows\\system32\\drivers")
print(r"c:\windows\system32\drivers")
转义符
\n \r
级联字符串
"this " "is " "string"
#equal
'this is string'
多次输出字符串
"hi"*3
字符串索引
'abc'[0] # a
'abc'[-1] # c
'abcd'[1:2] # b
'abcd'[1:3] # bc
'abcd'[2:] # cd
'abcd'[0:4] # abcd
# 变量[头下标:尾下标:步长]
#step指的是对截取的字符串的读取间隔
'aaabbbccc'[0:-1:3] # abc
文本编码/解码处理
# 把 Unicode 字符串转换为bytes字符串
bytesStr = b'ABC'
'abc'.encode('ascii') #b'ABC'
'abc'.encode('gb2312')#b'ABC'
'abc'.encode('utf-8')# b'ABC'
'中文'.encode('ascii') #error
'中文'.encode('gb2312') #b'\xd6\xd0\xce\xc4'
'中文'.encode('gbk') # b'\xd6\xd0\xce\xc4'
'中文'.encode('utf-8')#b'\xe4\xb8\xad\xe6\x96\x87'
b'ABC'.decode('ascii')
b'ABC'.decode('gb2312')
b'ABC'.decode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'.decode('gb2312')
b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'联通'.encode('gbk')#b'\xc1\xaa\xcd\xa8'
'联通'.encode('utf-8')#b'\xe8\x81\x94\xe9\x80\x9a'
b'\xc1\xaa\xcd\xa8'.decode('gbk', errors='ignore')
b'\xc1\xaa\xcd\xa8'.decode('utf-8', errors='ignore')
b'\xe8\x81\x94\xe9\x80\x9a'.decode('gbk', errors='ignore')
b'\xe8\x81\x94\xe9\x80\x9a'.decode('utf-8', errors='ignore')
len('联通')
len(b'\xe8\x81\x94\xe9\x80\x9a')
print(u'正常')
格式化
在Python中,采用的格式化方式和C语言是一致的,用%
实现
'Hello, %s' % 'world'
'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Age: %s. Gender: %s' % (25, True)
'Hello, {0}, 成绩提升了 {1:.2f}%'.format('小明', 17.125)
数字处理
常见的数学运算都支持,转换为数字的bif为
- int() , int(‘11’)
- bool(), bool(1)
- float(), float(“1.25”)
- complex(), complex(“1+2j”)
int("20")+int("30")
1+2 # 加 3
5-2 # 减 3
1*5 # 乘 5
4/2 # 除 2
7%2 # 求余 1
2**3 # 幂运算 8
floor除法(地板除法)
常规除法
5/2 # 2.5 # 是浮点数
floor除法
5//2 =2 # floor 的目的是结果是比实际结果(2.5)小的最大值,相对的有ceil
等同于
import math
math.floor(5/2) # 2
相关参考
import math
math.floor(5/2) # 2
math.ceil(5/2) # 3
对象处理
bif-dir()查看类上的方法
dir(string)
list
list是一种有序的集合,可以随时添加和删除其中的元素
classmates = ['Michael', 'Bob', 'Tracy']
classmates[1]
classmates[-1]
tuple
tuple和list非常类似,但是tuple一旦初始化就不能修改,不可变的tuple有什么意义?因为tuple不可变,所以代码更安全。如果可能,能用tuple代替list就尽量用tuple。
classmates = ('Michael', 'Bob', 'Tracy')
t0 = () # 空tuple
t1 = (1) # 是数字1
t2 = (1,) # 只有一个元素的tuple
dict
Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d['Michael']#取值
d['Jack'] = 90 #赋值
'Thomas' in d # 判断key是否存在
d.get('Thomas')# 不存在返回None
d.get('Thomas', -1)#不存在返回 -1
d.pop('Bob')# 删除key
set
set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。
s = set([1, 1, 2, 2, 3, 3])
s.add(4)
s.remove(4)
s1 = set([1, 2, 3])
s2 = set([2, 3, 4])
s1 & s2
s1 | s2
高级特性
切片
等同于一般语言中的substring、slice、splice操作
L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
L[0:3] # index 为 0 到 2的数据
L[:3] # index 为 0 到 2的数据
L[:] # 复制数组
(0, 1, 2, 3, 4, 5)[:3] # tuple 也可以
迭代(循环、遍历、枚举)enumerable
- enumerable 可枚举
for ch in 'ABC':
print(ch)
from collections import Iterable
isinstance('abc', Iterable) # str是否可迭代
isinstance([1,2,3], Iterable) # list是否可迭代
d = {'a': 1, 'b': 2, 'c': 3}
for key in d:
print(key)
for value in d.values()
for k, v in d.items()
for i, value in enumerate(['A', 'B', 'C']):
print(i, value)
for x, y in [(1, 1), (2, 4), (3, 9)]:
print(x, y)
列表生成式
# 操作 遍历 生成列表 过滤条件
[x * x for x in range(1, 11)]
[x * x for x in range(1, 11) if x % 2 == 0]
['line '+str(i) for i in range(1,11)]
[m + n for m in 'ABC' for n in 'XYZ']
import os # 导入os模块,模块的概念后面讲到
[d for d in os.listdir('.')] # os.listdir可以列出文件和目录
d = {'x': 'A', 'y': 'B', 'z': 'C' }
[k + '=' + v for k, v in d.items()]
生成器 generator
L = [x * x for x in range(3)]
g = (x * x for x in range(3))
next(g)
g = (x for x in range(3))
for n in g:
print(n)
变成generator的函数,在每次调用next()
的时候执行,遇到yield
语句返回,再次执行时从上次返回的yield
语句处继续执行。
要理解generator的工作原理,它是在for
循环的过程中不断计算出下一个元素,并在适当的条件结束for
循环。对于函数改成的generator来说,遇到return
语句或者执行到函数体最后一行语句,就是结束generator的指令,for
循环随之结束。
def fibonacci_number(n):
'''
斐波那契函数
'''
a, b = 0, 1
for i in range(0, n):
a, b = b, a + b
yield a
pass
for num in fibonacci_number(15):
print(num)
g = fibonacci_number(15)
while True:
try:
print(next(g))
except StopIteration as e:
print('Generator return value:', e.value)
break
迭代器 iterable/iterator
可以被next()
函数调用并不断返回下一个值的对象称为迭代器:Iterator
。
生成器就是迭代器
- 可迭代的对象 ,
list
、dict
、str
- 迭代器对象 , 生成器
from collections.abc import Iterable
isinstance([], Iterable)
from collections.abc import Iterator
isinstance((x for x in range(10)), Iterator)
isinstance(iter([]), Iterator)
# True
isinstance(iter('abc'), Iterator)
你可能会问,为什么list
、dict
、str
等数据类型不是Iterator
?
这是因为Python的Iterator
对象表示的是一个数据流,Iterator对象可以被next()
函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration
错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()
函数实现按需计算下一个数据,所以Iterator
的计算是惰性的,只有在需要返回下一个数据时它才会计算。
Iterator
甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。
赋值语句
numA=1
text="hi"
函数(方法)
定义
定义包含要素:名称、传入参数、返回值
def getNum(num):
return num
pass
调用函数
函数名()
getNum(5)
内置函数文档
http://docs.python.org/3/library/functions.html#abs
借助抽象,我们才能不关心底层的具体计算过程,而直接在更高的层次上思考问题。
写计算机程序也是一样,函数就是最基本的一种代码抽象的方式。
def getMax(a,b):
return max(a,b)
print(getMax(2,3))
空函数 pass
pass
语句什么都不做,那有什么用?实际上pass
可以用来作为占位符,比如现在还没想好怎么写函数的代码,就可以先放一个pass
,让代码能运行起来。
这才是一个空函数
def nop():
pass
这个不是
def nop():
参数类型检查
def my_abs(x):
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
if x >= 0:
return x
else:
return -x
函数返回多个值
import math
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny
函数默认参数
函数的参数 - 廖雪峰的官方网站
https://www.liaoxuefeng.com/wiki/1016959663602400/1017261630425888
一是必选参数在前,默认参数在后,否则Python的解释器会报错(思考一下为什么默认参数不能放在必选参数前面);
二是如何设置默认参数。
当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数。
使用默认参数有什么好处?最大的好处是能降低调用函数的难度。
默认参数必须指向不变对象!
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
函数参数类型检测
def printCharCode(text):
'''
输出文本对应的编码值
'''
# 参数检查-类型判断
if not isinstance(text, (str)):
raise TypeError('the arg [text] type need string type')
pass
可变参数
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
nums = [1, 2, 3]
calc(*nums)
关键字参数
关键字参数有什么用?它可以扩展函数的功能。比如,在person
函数里,我们保证能接收到name
和age
这两个参数,但是,如果调用者愿意提供更多的参数,我们也能收到。试想你正在做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('Adam', 45, gender='M', job='Engineer')
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra)
命名关键字参数
命名关键字参数需要一个特殊分隔符*
,*
后面的参数被视为命名关键字参数
def person(name, age, *, city, job):
print(name, age, city, job)
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*
了:
def person(name, age, *args, city, job):
print(name, age, args, city, job)
参数组合
可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
虽然可以组合多达5种参数,但不要同时使用太多的组合,否则函数接口的可理解性很差。
递归函数
递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。
尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
尾递归调用时,如果做了优化,栈不会增长,因此,无论多少次调用也不会导致栈溢出。
遗憾的是,大多数编程语言没有针对尾递归做优化,Python解释器也没有做优化,所以,即使把上面的fact(n)
函数改成尾递归方式,也会导致栈溢出。
# 会爆栈
def fact(n):
if n == 1:
return 1
return n * fact(n - 1)
pass
# 循环写法,不会爆栈
def fact2(n):
if n == 1:
return 1
sum= 1
for i in range(n,0,-1):
sum *=i
return sum
pass
# 尾调用方式,可惜py编译器没有实现尾调用优化,还是会爆栈
def fact3(n):
return fact_iter(n, 1)
def fact_iter(num, product):
if num == 1:
return product
return fact_iter(num - 1, num * product)
函数式编程 Functional Programming
函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。
函数式编程虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算。
我们首先要搞明白计算机(Computer)和计算(Compute)的概念。
在计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断和跳转指令,所以,汇编语言是最贴近计算机的语言。
而计算则指数学意义上的计算,越是抽象的计算,离计算机硬件越远。
对应到编程语言,就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如C语言;越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Lisp语言。
函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。
高阶函数
高阶函数英文叫Higher-order function。
一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
map()
map()
传入的第一个参数是f
,即函数对象本身。由于结果r
是一个Iterator
,Iterator
是惰性序列,因此通过list()
函数让它把整个序列都计算出来并返回一个list。
list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
reduce()
reduce
把一个函数作用在一个序列[x1, x2, x3, ...]
上,这个函数必须接收两个参数,reduce
把结果继续和序列的下一个元素做累积计算。
from functools import reduce
def add(x, y):
return x + y
print(reduce(add, [1, 3, 5, 7, 9]))
print(sum([1, 3, 5, 7, 9]))
from functools import reduce
DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def char2num(s):
return DIGITS[s]
def str2int(s):
return reduce(lambda x, y: x * 10 + y, map(char2num, s))
print(char2num('6'))
print(str2int('556'))
filter()
def not_empty(s):
return s and s.strip()
list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))
sorted()
sorted([36, 5, -12, 9, -21], key=abs)
返回值是函数
闭包
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
匿名函数
f=lambda x:x*x
f(3)
装饰器(Decorator)
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
@log
def now():
print('2015-3-25')
now()
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
def now():
print('2015-3-25')
log(now)
偏函数
int2 = functools.partial(int, base=2)
模块
每一个包目录下面都会有一个__init__.py
的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py
可以是空文件,也可以有Python代码,因为__init__.py
本身就是一个模块,而它的模块名就是mycompany
。
mycompany
├─ __init__.py
├─ abc.py
└─ xyz.py
from mycompany.abc import *
自己创建模块时要注意命名,不能和Python自带的模块名称冲突。例如,系统自带了sys模块,自己的模块就不可命名为sys.py,否则将无法导入系统自带的sys模块
模块定义格式
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' a test module '
__author__ = 'Michael Liao'
import sys
def test():
args = sys.argv
if len(args)==1:
print('Hello, world!')
elif len(args)==2:
print('Hello, %s!' % args[1])
else:
print('Too many arguments!')
if __name__=='__main__':
test()
当我们在命令行运行hello
模块文件时,Python解释器把一个特殊变量__name__
置为__main__
,而如果在其他地方导入该hello
模块时,if
判断将失败,因此,这种if
测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。
模块导入 import 与 from...import
在 python 用 import
或者 from...import
来导入相应的模块。
将整个模块(somemodule)导入,格式为: import somemodule
从某个模块中导入某个函数,格式为: from somemodule import somefunction
从某个模块中导入多个函数,格式为: from somemodule import firstfunc, secondfunc, thirdfunc
将某个模块中的全部函数导入,格式为:from somemodule import *
运算符优先级
一般不需要记住下面的优先级,使用括号分隔优先级即可
**
+x -x
* / // + -
< <= > >= == !=
not and or
注释
#
号就是行注释
name="tom" # name is tom
'''
三个单引号注释
'''
"""
三个双引号注释
"""
帮助命令
通过 bif help方法来处理
help(str) #查看 str 类的帮助说明
help(str.upper) #查看 str.upper 方法的帮助说明
查看所有关键字
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import keyword
keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'async', 'await', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
等待用户输入
#!/usr/bin/python3
input("\n\n按下 enter 键后退出。")
同一行显示多条语句
#!/usr/bin/python3
import sys; x = 'runoob'; sys.stdout.write(x + '\n')
print输出
#!/usr/bin/python3
# -*- coding: utf-8 -*-
x="a"
y="b"
# 换行输出
print( x )
print( y )
print('---------')
# 不换行输出
print( x, end=" " )
print( y, end=" " )
print()
BIF(built-infunctions)
dir(__builtins__)
可以看到python的内置方法列表
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
int()
int("22") # 22
str()
str(22) # "22"
max()
max(1,5,2) # 5
min()
min(1,5,2) # 1
type()
Python type() 函数 | 菜鸟教程
https://www.runoob.com/python/python-func-type.html
isinstance() 与 type() 区别:
- type() 不会认为子类是一种父类类型,不考虑继承关系。
- isinstance() 会认为子类是一种父类类型,考虑继承关系。
如果要判断两个类型是否相同推荐使用 isinstance()。
type("hi") #<class 'str'>
type(22) #<class 'int'>
isinstance()
isinstance(1,int) # True
isinstance("1",str) # True
isinstance(1,str) # False
保留字
下面的列表显示了在Python中的保留字。这些保留字不能用作常数或变数,或任何其他标识符名称。
所有 Python 的关键字只包含小写字母。
and | exec | not |
---|---|---|
assert | finally | or |
break | for | pass |
class | from | |
continue | global | raise |
def | if | return |
del | import | try |
elif | in | while |
else | is | with |
except | lambda | yield |
OOP
类
属性和方法
继承
主线类继承,支线接口继承
多态
错误处理
- 参数类型数据判断
- 错误通过错误码的形式返回
- 错误通过异常抛出
- 捕获异常并处理 try…catch…finally
- 在合适的地方需要主动抛出异常 raise ValueError()
调试
- assert 断言
测试
- 单元测试
- 文档测试
I/O
- 同步io
- 异步io 回调模式 轮询模式,复杂度高
读文件
读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统提供的,现代操作系统不允许普通的程序直接操作磁盘,所以,读写文件就是请求操作系统打开一个文件对象(通常称为文件描述符),然后,通过操作系统提供的接口从这个文件对象中读取数据(读文件),或者把数据写入这个文件对象(写文件)。
f=open('/Users/michael/notfound.txt', 'r')
f.read()
f.close()
try:
f = open('/path/to/file', 'r')
print(f.read())
finally:
if f:
f.close()
with open('/path/to/file', 'r') as f:
print(f.read())
写文件
f = open('/Users/michael/test.txt', 'w')
f.write('Hello, world!')
f.close()
序列化
我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
Python提供了pickle
模块来实现序列化。
Tkinter HelloWorld
Python Tkinter学习(1)——第一个Tkinter程序 - collectionne - 博客园
https://www.cnblogs.com/collectionne/p/6885066.html
from tkinter import *
root = Tk()
root.geometry("300x200+100+50")
root.mainloop()
from tkinter import *
import tkinter.messagebox as messagebox
class Application(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.pack()
self.createWidgets()
def createWidgets(self):
self.nameInput = Entry(self)
self.nameInput.pack()
self.alertButton = Button(self, text='Hello', command=self.hello)
self.alertButton.pack()
def hello(self):
name = self.nameInput.get() or 'world'
messagebox.showinfo('Message', 'Hello, %s' % name)
app = Application()
# 设置窗口标题:
app.master.title('Hello World')
# 主消息循环:
app.mainloop()
turtle
长方形
# 导入turtle包的所有内容:
from turtle import *
# 设置笔刷宽度:
width(4)
# 前进:
forward(200)
# 右转90度:
right(90)
# 笔刷颜色:
pencolor('red')
forward(100)
right(90)
pencolor('green')
forward(200)
right(90)
pencolor('blue')
forward(100)
right(90)
# 调用done()使得窗口等待被关闭,否则将立刻关闭窗口:
done()
五星好评
from turtle import *
def drawStar(x, y):
pu()
goto(x, y)
pd()
# set heading: 0
seth(0)
for i in range(5):
fd(40)
rt(144)
for x in range(0, 250, 50):
drawStar(x, 0)
done()
分型树
from turtle import *
# 设置色彩模式是RGB:
colormode(255)
lt(90)
lv = 14
l = 120
s = 45
width(lv)
# 初始化RGB颜色:
r = 0
g = 0
b = 0
pencolor(r, g, b)
penup()
bk(l)
pendown()
fd(l)
def draw_tree(l, level):
global r, g, b
# save the current pen width
w = width()
# narrow the pen width
width(w * 3.0 / 4.0)
# set color:
r = r + 1
g = g + 2
b = b + 3
pencolor(r % 200, g % 200, b % 200)
l = 3.0 / 4.0 * l
lt(s)
fd(l)
if level < lv:
draw_tree(l, level + 1)
bk(l)
rt(2 * s)
fd(l)
if level < lv:
draw_tree(l, level + 1)
bk(l)
lt(s)
# restore the previous pen width
width(w)
speed("fastest")
draw_tree(l, 4)
done()
发表评论