一 python3
1. python风格
- 约定:
- 使用4个空格缩进
- 不混淆空格和制表符
- 函数之间空一行
- 类之间空两行
- 字典,列表,元组及参数列表中,号后加空格 字典的:后也加个空格
- 赋值和比较uansu符周围有空格
2. 注释
- # FIXME --fix these code later
- # TODO --to do this in future
3. 模块
- 模块以.py为扩展名
- 使用模块前先引用 > import math
二 变量和数据类型
1.关键字和标识符
help()
keywords
python变量不需要指定类型
2.键盘上读取输入
num = int(input("enter an integer pls."))
year = 2
value = 13.2323
print("year {} rs. {:.2f}").format(year,value) #字符串格式化
- str.format()
#!/usr/bin/env python3
fahrenheit = 0
print("Fahrenheit Celsius")
while fahrenheit <= 250:
celsius = (fahrenheit - 32) / 1.8 # 转换为摄氏度
print("{:5d} {:7.2f}".format(fahrenheit , celsius))
fahrenheit = fahrenheit + 25
3.单行定义多个变量或赋值
a , b = 45, 23
a ,b = b ,a #交换数值
- 赋值语句右边成为tuple packing
- 左边称为tuple unpacking
三 运算符和表达式
1.运算符
- / 除
- //整除
- %取余
print("months = {} days = {}".format(months, days))
divmod(num1, num2) 返回一个元组,这个元组包含两个值,第一个是 num1 和 num2 相整除得到的值,第二个是 num1 和 num2 求余得到的值
2.关系运算符
- <, <=, >, >=, ==, !=
3.逻辑运算符
- and, or, not
- a += 1等价于a = a + 1
4.表达式
- a = 234*(45 - 34/3)
5.类型转换
- float(str)
- int(str)
- str(int)
- str(float)
四 控制流 if...else
if x: #判断真值的优雅方式
pass
五 循环
1.while
#斐波那契数列
#!/usr/bin/env python3
a, b = 0, 1
while b < 100:
print(b)
a, b = b, a + b
- print(b, end=' ') #end参数代替换行符\n
2.幂级数
#!/usr/bin/env python3
x = float(input("Enter the value of x: "))
n = term = num = 1
result = 1.0
while n <= 100:
term *= x / n
result += term
n += 1
if term < 0.0001:
break
print("No of Times= {} and Sum= {}".format(n, result))
3.乘法表
#!/usr/bin/env python3
i = 1
print("-" * 50)
while i < 11:
n = 1
while n <= 10:
print("{:4d}".format(i * n),end=' ')
n += 1
print()
i += 1
print("-" * 50)
4.列表
5.for循环
6.range()函数
- list(range(5))
- tuple(range(5))
- set(range(5))
- dict(enumerate(range(5)))
7.continue语句
跳过其后的代码回到循环开始处执行
while True:
n = int(input("enter an integer: ))
if n < 0:
continue
elif n == 0:
break
print("square is "n ** 2)
print("byebye")
8.else语句
六 数据结构
1.列表
- 列表推导式 squares = list(map(lambda x:x**2 ,range(10)))
- [(,y) for x in [1,2,3] for y in [3,1,4] if x !=y]
2.元组
- x, y = divmod(15,2)
- 元组不可变
3.集合
4.字典
- dict.setdefault('names',[]).append('rudy')
- dict.get(key,default) #索引键,判断是否存在
- enumerate(['a','b','c']) 遍历列表的同时获得元素的索引
- for x ,y in zip(a,b):pass 同时遍历两个序列类型
七 字符串
1.字符串方法
- s.split(":") #指定分割符
- s.title() #首字母大写
- s.upper() #全大写
- s.lower()
- s.swapcase() #交换大小写
- s.isalnum() #判断所有字符是否是字母数字
- s.isalpha() #判断是否只有字母
- s.isdigit()
- s.islower()
- s.istitle()
- "--".join("hey hey".split()) #指定字符连接字符串
2.字符串剥离
- s.strip("adfg") #剥离字符串尾部指定的字符
- lstrip()
- rstrip()
3.文本搜索
- s.find("for")
- s.startsdwith("fa")
- s.endswith('endd')
4.回文检查
回文从左右读都是一样的 如madam
z = s[::-1] #反转字符
八 函数
1.函数定义
def sum(a,b):
return a + b
2.局部和全局变量
- global a #声明a是全局的
3.默认参数
def foo(a, b= 99):pass
def f(a, data=None):pass
4.关键字参数
def func(a, b=5 ,c =10):pass
func(12,b=4,c=12)
5.强制关键字参数
def func(*,name='user'):pass
func(name ='max')
6.文档字符串docstrings
print(func._doc_)
7.高阶函数
- map函数 接受一个函数和序列作为输入,然后对序列的每个值应用函数,返回一个序列
九 文件处理
1.文件打开
open() 方法
close()
2.文件读取
f.read()
f.readline() #每次都读取文件的一行
f.readlines() #读取文件的所有行到一个列表
for x in open('sample.txt'): print(x,end='')
3.文件写入
f = open('test.txt','w')
f.write('pork\n')
f.close()
4.文件操作示例
#!/usr/bin/env python3
import sys
if len(sys.argv) < 3:
print("Wrong parameter")
print("./copyfile.py file1 file2")
sys.exit(1)
f1 = open(sys.argv[1])
s = f1.read()
f1.close()
f2 = open(sys.argv[2], 'w')
f2.write(s)
f2.close()
for i,x in enumerate(sys.argv):
print(i,x) #返回参数的序号和参数
- 文件相关信息统计
#!/usr/bin/env python3
import os
import sys
def parse_file(path):
"""
分析给定文本文件,返回其空格、制表符、行的相关信息
:arg path: 要分析的文本文件的路径
:return: 包含空格数、制表符数、行数的元组
"""
fd = open(path)
i = 0
spaces = 0
tabs = 0
for i,line in enumerate(fd):
spaces += line.count(' ')
tabs += line.count('\t')
#现在关闭打开的文件
fd.close()
#以元组形式返回结果
return spaces, tabs, i + 1
def main(path):
"""
函数用于打印文件分析结果
:arg path: 要分析的文本文件的路径
:return: 若文件存在则为 True,否则 False
"""
if os.path.exists(path):
spaces, tabs, lines = parse_file(path)
print("Spaces {}. tabs {}. lines {}".format(spaces, tabs, lines))
return True
else:
return False
if __name__ == '__main__':
if len(sys.argv) > 1:
main(sys.argv[1])
else:
sys.exit(-1)
sys.exit(0)
5.with语句
十 异常
- NameError
- TypeError
- KeyboardInterrupt Ctrl+c
- try ... except ...
1.抛出异常
raise语句
2.定义清理行为
try...finally...
十一 类
_init_方法
类定义了 _init_() 方法的话,类的实例化操作会自动为新创建的类实例调用 _init_() 方法继承
多继承
del删除对象 #del实际上使对象的引用计数减少一,当对象的引用计数变成零时,垃圾回收器会删除这个对象。
- properties装饰器
@property装饰器精确调整控制属性访问权限,把方法变成属性调用
#!/usr/bin/env python3
class Account(object):
"""账号类,
amount 是美元金额.
"""
def __init__(self, rate):
self.__amt = 0
self.rate = rate
@property
def amount(self):
"""账号余额(美元)"""
return self.__amt
@property
def cny(self):
"""账号余额(人名币)"""
return self.__amt * self.rate
@amount.setter
def amount(self, value):
if value < 0:
print("Sorry, no negative amount.")
return
self.__amt = value
if __name__ == '__main__':
acc = Account(rate=6.6) # 基于课程编写时的汇率
acc.amount = 20
print("Dollar amount:", acc.amount)
print("In CNY:", acc.cny)
acc.amount = -100
print("Dollar amount:", acc.amount)
十二 模块
- _name_ 变量得到模块名
- 模块导入 不推荐使用from module import *
1.包
- 含有_init_.py 的目录作为包,里面有子模块
- _init_.py文件内有名为_all_的列表,则只有在列表内列出名字将会被公开,_all_ =[ss,] 导入时只有ss模块可用
2.os模块
- os.getuid()
- os.getpid(),os.getppid()
- os.uname() #返回系统信息的元组
- os.getcwd(),os.chdir('/test')
- os.listdir(''/')
3.requests模块
requests是第三方模块,http库
安装第三方模块的先安装pip3
sudo apt-get install update
sudo apt-get install python3-pip
sudo pip3 install requests
- 获得网页
import requests
req = request.get('http://www.baidu.com')
req.status_code
#!/usr/bin/env python3
import os
import os.path
import requests
def download(url):
req = requests.get(url)
if req.status_code == 404:
print('no such file found at %s' % url)
return
filename = url.split('/')[-1]
with open(filename,'wb') as f:
f.write(req.content)
print("download completed")
if __name__ == '__main__':
url = input("enter a url:")
download(url)
4.命令行参数
- argparse 模块
5.tab补全
vim ~/.pythonrc
import rlcompleter, readline
readline.parse_and_bind('tab: complete')
history_file = os.path.expanduser('~/.python_history')
readline.read_history_file(history_file)
import atexit
atexit.register(readline.write_history_file,history_file)
vim ~/.bashrc
export PYTHONSTARTUP=~/.pythonrc
source ~/.bashrc
十三 collections模块
import collections
collections.Counter._doc_
1.Counter示例
from collections import Counter
import re
path = 'test.txt'
words = re.finall('\w+',open(path).lower())
Counter(words).most_common(10)
c = Counter(a=4,b=2,c=0,d=-2)
list(c.elements()) #返回依照计数重复元素的序列
- most_common()方法返回最常见的元素及计数
Counter('adaadadadadade').most_common(3)
2.defaultdict
from collections import defaultdict
s= [('yellow',1),('blue',2),('yellow',3),('red',1)]
d = defaultdict(list)
for k, v in s:
d[k].append(v)
d.items()
3.namedtuple
命名元组有助于对元组每一个位置赋予意义,且让代码有更好的可读性和自文档性
from collections import namedtuple
Point = namedtuple('Point',['x','y']) #定义命名元组
p = Point(10,y=20)
p.x + p.y
十四 PEP8代码风格指南
代码排版
缩进 4个空格
制表符和空格 不可以混用
每行最大长度79字符
顶级函数和类定义使用两个空行
源文件编码应该总是utf-8
导入包
import不同模块独立一行
import语句总是在文件顶部
-
import语句分组顺序:
- 导入标准库
- 导入第三方
- 导入当前应用程序/库模块
- _all_声明本文件内的模块
绝对导入和相对导入
一个包含类的模块导入类可以的
尽量避免from module import *
字符串引号 单引号和双引号是相同的
表达式和语句中的空格
括号内避免使用多余的空格
逗号/分号/冒号保持紧凑
切片中冒号两侧必须有相同的空格数量
函数名和其后的参数列表括号保持紧凑
等等
二元操作符两侧加一个空格
关键字参数或默认值参数等号两边不需要空格
最好不要多条命令在一行的符合语句
注释
块注释
行内注释
文档字符串aka docstrings
版本注记
_version_ = ""命名约定 内部一致性
覆盖原则 API对用户可见部分应该遵守约定
规定:命名约定 驼峰命名CamelCase/StudlyCaps
_all_机制表明可导出的全局变量
总是使用self作为实例方法的第一个参数
总是使用cls作为类方法的第一个参数
pythonic指南
- 共有属性不应有前下划线
- 如果你的公有属性与保留关键字发生冲突,在你的属性名后面添加一个尾随的下划线。
- 对于简单的公有数据属性,最好的方式是暴露属性名,不要使用复杂的访问属性/修改属性的方法。
- 如果你的类是为了被继承,你有不想让子类使用的属性,给属性命名时考虑给它们加上双前导下划线,不要加尾随下划线。
公共和内部接口
为了更好的支持内省,模块应该用all属性来明确规定公有 API 的名字。
内部接口(包、模块、类、函数、属性或者其它的名字)应该有一个前导的下划线前缀。
程序编写的建议
eq 、 ne 、 lt , le, gt , ge
用is not操作符而不是not ... is
比较单例,像None应该用is或is not,从不使用==操作符
比较单例,像None应该用is或is not,从不使用==操作符
def比lambda表达式好
异常类应派生自Exception而不是BaseException
适当的使用异常链
在 Python 2 里抛出异常时,用raise ValueError('message')
捕获异常时,尽可能使用明确的异常,而不是用一个空的except:语句。
坚持使用return语句
用字符串方法代替字符串模块
用''.startswith()和''.endswith()代替字符串切片来检查前缀和后缀。
对于序列(字符串、列表、元组)来说,空的序列为False if not seq:
十五 迭代器,生成器,装饰器
1.迭代器interators支持方法
- _iter_()返回迭代器自身
- _net_()返回迭代器的写一个值
2. 生成器 generators
- 通过yield语句完成,生成器不可以重复使用
>>> def infinite_generator(start=0):
... while True:
... yield start
... start += 1
...
>>> for num in infinite_generator(4):
... print(num, end=' ')
... if num > 20:
... break
...
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
- 生成器表达式
生成器表达式是列表推导式和生成器的高性能的推广
sum([xx for x in range(1,10)])
sum(xx for x in range(1,10)) #更节省内存
3. 闭包closures闭包去除重复的代码
>>> def add_number(num):
... def adder(number):
... #adder 是一个闭包
... return num + number
... return adder
...
>>> a_10 = add_number(10)
>>> a_10(21)
31
4. 装饰器decorator
装饰器用来给一些对象动态添加一些新的行为
十六 virtualenv
为开发提供不同的环境
1.安装
sudo apt-get update
sudo apt-get install python3-pip
sudo pip3 install virtualenv
2.用法
- mkdir
- cd virtual
- virtual virt1 #创建virt1环境
- source virt1/bin/activate #激活virt1环境
- sudo pip3 install redis #在这个环境下安装redis模块
- deactivate #关闭虚拟环境
十七 测试
1.单元测试unit testing
- 单元测试模块unittest
import sys
def fact(n):
"""
阶乘函数
:arg n: 数字
:returns: n 的阶乘
"""
if n == 0:
return 1
return n * fact(n -1)
def div(n):
"""
只是做除法
"""
res = 10 / n
return res
def main(n):
res = fact(n)
print(res)
if __name__ == '__main__':
if len(sys.argv) > 1:
main(int(sys.argv[1]))
- assert语句
- 异常测试
- 测试覆盖率
sudo pip3 install coverage
coverage3 run test.py
十九 项目结构
1.
- 模块名myfact
mkdir myfact
- 主代码
factorial.py
cat __init__.py
from fact import factorial
__all__ = [factorial,]
- MAINFEST.in文件
include *.py
include README.rst
- 安装python-setuptools包
sudo pip3 install setuptools
- setup.py文件
#!/usr/bin/env python3
"""Factorial project"""
from setuptools import find_packages, setup
setup(name = 'factorial',
version = '0.1',
description = "Factorial module.",
long_description = "A test module for our book.",
platforms = ["Linux"],
author="ShiYanLou",
author_email="support@shiyanlou.com",
url="https://www.shiyanlou.com/courses/596",
license = "MIT",
packages=find_packages()
)
2.创建一个源文件发布版本
python3 setup.py sdist
suduo python3 setup.py install
3.python package index(PyPI)
- 创建账号
- vi ~/.pypirc
[distutils]
index-servers = pypi
testpypi
[pypi]
repository: https://upload.pypi.org/legacy/
username: <username>
password: <password>
[testpypi]
repository:https://test.pypi.org/legacy/
username: <username>
password: <password>
- 上传到TestPyPI
sudo pip3 install twine
twine upload dist/* -r testpypi
twine upload dist/* -r pypi