- 作者:
- 分类:知识&开发->语言->Python
- 阅读:17479
- 点赞:83
- 版权:CC BY-SA 4.0
- 创建:2019-10-13
- 更新:2020-10-10
原文链接(持续更新):https://neucrack.com/p/59
本文主要是简单介绍,具体大量的函数库的使用不会具体说明, 比如对于list类型会简单介绍概念,具体它相关的方法需要看文档或者其它更详细的教程
简介
Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言
python, 英文翻译为蟒蛇, 也可以看到它的 logo 也是两条不同颜色的蛇
1991年发行, 创始人为荷兰人吉多·范罗苏姆(Guido van Rossum)
python的实现也有很多版本, 主要使用的是python.org的版本(也就是CPython), 到现在实现分别有python2和python3两个大版本
特征
- 跨平台脚本语言
- 不需要编译, 解释型语言,语法检查也是在运行时
- 使用缩进符号来作为域分隔,作用类似
C中的大括号(所以你的编辑器一定要注意缩进符号设置,建议设置成4个空格) - 面向对象语言
开源, 也免费,开源协议看这里
优点:
- 语法简单易学,好入门
- 可读性高
- 内置库和语法好用, 代码好读懂,编写代码快
- 各种现成的库,数量庞大,安装和引入非常简单
- 综上两点,节省头发和生命
- 可扩展性, 可方便地引入其它模块,以及其它语言编写的模块
- 缺点:
- 解释型语言, bug需要在运行后才能知道,那怕是语法错误(因为没有编译这一步), 所以测试要覆盖率高才行
- 解释型语言, 相比于编译型语言,运行效率低(注意这还跟程序的写法有很大关系), 所以一些关键的耗费性能的部分还是需要调用其它语言写的库
- 入门太容易
应用场景
- 脚本, 类似 shell 脚本的用法, 用来方便日常各种任务的自动化, 包括朋友圈天天发的办公自动化广告= =
- 自动化测试, 比如web自动化测试可以使用
selenium库 - 爬虫, 有大量好用的库,以及很多参考项目
web服务器,有很多现成的框架比如 Flask, Django, FastAPI 等- 科学计算, 有大量科学计算的库如 numpy matplotlib SciPy等
- 图形处理,如opencv VTK ITK
- 机器学习, 已有的库比如 TensorFlow 等
- 桌面软件开发, 对于桌面软件也有很多GUI框架, 比如 pyqt5, Kivy, wxPython, Tkinter 等
- 嵌入式开发, 没错,有嵌入式实现
Micropython, 包括我们做的MaixPy也是基于Micropython - 游戏开发, 有很多游戏开发库如pygame,cocos2d,panda3d等
第一次遇见的很多问号
- 能取代 C/C++ 么?
回答: 不能 - 除了CPython还有哪些实现
回答: 比如 Jython(基于java编写), IronPython(基于.net框架), PyPy(基于RPython的实现,利用JIT(Just In Time 编译)来加快执行速度)
安装
下载 python3 (如果新学就不要学
python2了)。 windows需要去官网下载, 然后命令执行pip3 install pyreadline(tab补全); 在linux mac中默认已经安装了, 命令是python3(python命令默认可能是python2), 以下均用python表示python3, 除非特殊说明运行程序, 比如取名
soft.pyprint("hello python")
直接使用
python soft.py即可运行软件soft.py。如果不支持中文, 可以设置一下系统语言(unix)
export LC_ALL=C.UTF-8export LANG=C.UTF-8
加入到~/.bashrc或者~/.zshrc
安装其它程序
Python提供了包管理器pip(英语发音[pɪp],中国很多也读成pipe一样的读音,看你喜欢),使用pip安装软件pip install soft_name,更多方法看官方文档
另外, 如果从默认的国外的源下载太慢,可以设置国内的源,比如以下几个:IDE
pycharm,或者vscode装python插件或者更多其它的可以自己发掘
寻找库
发布
源码直接发布, 比如我写的这个串口助手
二进制发布,打包成平台对应的可执行文件, 比如 windows 的 exe, macOS 的 dmg
使用py2exe、cx-freeze、pyInstaller(推荐)等工具来进行打包,这种打包方式会将环境和依赖一同打包进软件,用户使用时下载软件包后可以直接运行,不需要用户自己安装Python。
比如cx-free打包:参考:http://www.cnblogs.com/zhongtang/p/5699322.html
建议使用pyinstaller, 比如pyinstaller --add-data="kflash_gui_data:kflash_gui_data" --add-binary="kflash_py:kflash_py" -i="kflash_gui_data/assets/logo.ico" -w kflash_gui.py
作为一个模块或者软件在pypi.org发布, 用户使用包管理工具
pip安装,将工程设置为pip可以安装的方法参见官方说明,这样用户使用的时候只需使用pip install softName就可以安装软件啦
虚拟环境
- 如果需要对某个工程使用特定的环境,使用
virtualenvpip3 install virtualenvvirtualenv --no-site-packages venv # venv是虚拟环境的名称source venv/bin/activate #激活虚拟环境deactivate # 退出虚拟环境
- 如果需要在一台电脑上安装多个环境(不同python版本,同时还可以不同包),可以用
conda(miniconda(推荐), Anaconda都可以)conda create --name test python=3.7conda activate test #激活环境conda list # 展示已经安装了的包conda deactivate # 退出环境
基本语法
查看模块帮助信息
import jsonprint(dir(json))help(json)
打印
print("hello")print("hello", "no return" , end="")print("hello")
注释
- 行注释:
#开头 - 段注释: 三引号
############## 这是注释#############'''这也是注释'''"""这也是注释"""
另外,在文件头声明
#! /usr/bin/env python3
可以使用./文件名.py直接执行
缩进
这是python 和其它语言非常不同的一点, 其它语言很多都用大括号来分隔函数条件循环等, python使用缩进, 可以使用tab或者空格, 所以这里也需要十分注意,tab和空格是不一样的,在写程序时需要使用一样的,最好编辑器设置好tab自动转换为4个空格
def func():print("hello") # 这里使用了tab按键
def func2():print("hello") # 这里使用了空格
注意如果在一个文件内即用空格又用tab就会报格式错误
多行
和其它语言一样使用\ 符号来换行, 如果是list, dict等对象,不需要,比如:
a = [1,2,3,4]b = {"aaa": 123}
等待用户输入
a = input("请输入内容")print(a)
同一行多个语句
print("aaa"); print("bbb")
变量
直接赋值,不需要声明类型
a = 10print(type(a))print(a)
注意 全局变量使用
- 全局变量在函数中使用需要注意:获取值可以直接使用,但是如果要赋值一定要 global 声明, 不然是定义一个新的局部变量
g = 10def test():print(g)def test2():g = 20def test3():global gg = 30print(test())print(test2())print(g)print(test3())print(g)
- nonlocal 使用
def outer():num = 10def inner():nonlocal num # nonlocal关键字声明num = 100print(num)inner()print(num)outer()
类型
可以用type(变量)来获取变量类型
str: 字符串, bytes:字节
字符串可以用单引号或者双引号或者三引号, 可以嵌套, 比如'string:"hello"', 不需要转义符,很方便。
三引号是可以扩一整段,包括多行,注意不赋值给变量可以当成注释功能
python 里面字符串分为两种, 一个是
ascii字节码, 另一个unicode字符串str_bytes = b'12\xe5\x93\x88\xe5\x93\x88\xe5\x93\x88\xe5\x93\x88'str_unicode = '12哈哈哈哈'print(str_unicode.encode('utf-8') == str_bytes)print(str_unicode == str_bytes.decode())
字串: 下标取,
字符串的常见函数,直接在终端中输入变量按tab补全就有了, 或者看文档
这里说一下格式化字符串:
第一种,类似c的printf:my_str = 'hello %.2f %04d %s' %(1.23456, 12, "good")print(my_str)
或者
format:my_str = 'hello {:.2f} {:04d} {}'.format(1.23456, 12, "good")print(my_str)
转义符号:
\,如果不想字符串被转义,在字符串前面添加r,比如`r’hello\n’’去掉行末空格 行首空格
s = ' 123 'print(s.strip())print(s.lstrip())print(s.rstrip())
list: 列表, 类似 C 中的数组
a = [1,2,3,4, "hello"]
- 取子list
a = [1,2,3,4,5]print(a[0:3]) # [1,2,3]
冒号 :, [i:j], i是开始(默认0),j是结束(默认len ), 也可以负数,表示从后往前数,比如[-2:-1]就是去倒数第2个数据
两个冒号 ::, 实际上是[i:j:s],
- 当
s>0:i默认0,j默认len,s默认值1代表步进. 步进为1的情况就和使用一个冒号一样了 - 当
s<0:i默认-1,j默认-len-1,代表步进, 比如-1就代表反向步进1
iter迭代器
迭代是Python最强大的功能之一,是访问集合元素的一种方式。
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter() 和 next()。
list=[1,2,3,4]it = iter(list) # 创建迭代器对象for x in it:print (x, end=" ")
tuple:元组, 不可更改
a = (1,2,3,4, "hello")
set, frozenset: 与数学中集合的概念类似。无序的、每个元素唯一。
{4.0, 'string', True}frozenset([4.0, 'string', True])
dict: 字典, 键值对
d = {'key1': 1.0,3: False}print(d)
int, float, bool:证书浮点数布尔
a = 10b = 1.234print(a, b, int(b))a = Trueb = False
注意 True``False大写开头
complex: 复数
3+2.7j
range: 按顺序排列的数
a = range(10)a = range(0, 10)print(list(a))
运算符
几乎和其它语言一样, +-*/, <<, >> | &, 或是or, 与是and, 非是not
a = 10if not 0 and a==10:print("hello")
常用转换函数
str(x): 将对象 x 转换为字符串int(x [,base]): 将x转换为一个整数float(x): 将x转换到一个浮点数complex(real [,imag]); 创建一个复repr(x): 将对象 x 转换为表达式字符串eval(str): 用来计算在字符串中的有效Python表达式,并返回一个对象tuple(s): 将序列 s 转换为一个元组list(s): 将序列 s 转换为一个列表set(s): 转换为可变集合dict(d): 创建一个字典。d 必须是一个 (key, value)元组序列。frozenset(s): 转换为不可变集合chr(x): 将一个整数转换为一个字符ord(x): 将一个字符转换为它的整数值hex(x): 将一个整数转换为一个十六进制字符串oct(x): 将一个整数转换为一个八进制字符串
函数
def test(arg, optional=10):print(arg, optional)test()
类
class Base:a = 10b = 20__private_v = 10class AAA(Base):def __init__(self, arg):print(arg)print(a)def __del__(self):passvarA = AAA(123)print(varA.a, varB.b, AAA.a, AAA.b)varA.a = 100AAA.a = 999AAA.b = 888print(varA.a, varB.b, AAA.a, AAA.b)
需要注意的类的变量的对象的变量, 对象的变量要在构造函数
__init__中使用self.a这样定义,
类变量要直接在类中定义,就像上面Base类的a变量。
每个对象都会有这个类变量,但是对象一旦修改了这个类变量,这个类变量就变成了这个对象专有的对象变量了,通过类名修改这个变量也不会影响到这个对象变量注意,这里每个成员函数的
self参数就是对象, 不是类, 类成员用类名调用__两个下划线开头表示是私有变量调用父类方法:
super(Class, obj).func()返回多个参数: 返回一个元组或者列表类型即可
匿名函数
lambda:add = lambda x,y:x+yprint(add(3,4))
闭包函数(返回函数)
#闭包函数,其中 exponent 称为自由变量def nth_power(exponent):def exponent_of(base):return base ** exponentreturn exponent_of # 返回值是 exponent_of 函数square = nth_power(2) # 计算一个数的平方cube = nth_power(3) # 计算一个数的立方print(square(2)) # 计算 2 的平方print(cube(2)) # 计算 2 的立方
函数注解(
decorator)
本质上,decorator就是一个返回函数的高阶函数.def log(func):def wrapper(*args, **kw):print('call %s()' % func.__name__)return func(*args, **kw)return wrapper@logdef now():print('2015-3-25')#call now()#2015-3-25
偏函数
from functools import partialdef mod( n, m ):return n % mmod_by_100 = partial( mod, 100 )print mod( 100, 7 ) # 2print mod_by_100( 7 ) # 2bin2dec = partial( int, base=2 )print bin2dec( '0b10001' ) # 17print bin2dec( '10001' ) # 17
- 参数,返回值类型指定:
输出为:def add(num1: int, num2: int=100) -> int:sum = num1 + num2return sum#if __name__ == "__main__":print(add.__annotations__)print(add(1,2))print(add(1))print(add('test1', 'test2'))
{'num1': <class 'int'>, 'num2': <class 'int'>, 'return': <class 'int'>}3101test1test2
控制语句
if:a = 1if a == 1:print("hello")elif a == 2:print("hello 2")else:print("hello 3")
for:循环迭代器for i in range(0, 10):print(i)`
while:循环count = 0while 1:print("hello")count += 1if count < 2:continuebreak
try:捕获import tracebackimport systry:raise Exception("error lalala")except Exception as e:print("error:", e)traceback.print_exc()err_info2 = sys.exc_info()traceback.print_tb(err_info2[2])else:print("no error")finally:print("finally")
这里用了
traceback.print_exc()或者sys.exc_info()来打印出错的行数等信息traceback.print_exc()原型是print_exception(etype, value, tb[,limit[, file]])
pass: 表示此行为空,不运行任何操作。assert: 用于程序调试阶段时测试运行条件是否满足。
with:with open("file.txt") as f:print(f.read())
yield: 在迭代器函数内使用,用于返回一个元素。自从Python 2.5版本以后。这个语句变成一个运算符。
in: 判断一个对象是否在一个字符串/列表/元组里。for i in range(0, 10):print(i)l = [1,2,3]print(2 in l)
import: 导入一个模块或包。from … import: 语句,从包导入模块或从模块导入某个对象。import … as: 语句,将导入的对象赋值给一个变量(别名)。
常用全局变量
__name__: 当文件或模块被python直接执行比如python test.py则这个文件这个变量的值为__main__,否则为包名, 所以可以利用这个来区分是被当成模块调用还是直接执行, 一般在文件中写:def test():print("test")if __name__ == "__main__":test()
__file__: 当前文件的路径, 注意以相对路径运行文件可能是相对路径, 可以用os.path.abspath(__file__)获取绝对路径__all__: 指定模块内哪些变量能被import使用
def test():print("hello")def test2():print("test2")__all__ = ['test'] # 如果使用 from var import test2 会报错# 但是使用import var; var.test2()可以使用# 直接执行文件也是都可以访问的
模块
一个模块是一个文件夹, 下面有一个__init__.py, 这里面的内容就是模块的内容, 也可以在文件夹下建其它文件
test├─ __init__.py├─ aaa.py└─ bbb.py
使用:
import testfrom test import aaa, bbbfrom test.aaa import *
常见模块及使用方法
后台运行及时打印日志到文件
执行命令时加 -u 参数,
(python -u test.py > teset.log 2>&1 &)
文件操作
with open("文件名", 'r') as f:print(f.read())
f = open("文件名", 'r')print(f.read())f.close()
更多可以看其它教程
文件、文件夹、路径操作
import sysimport osimport shutilimport globos.getcwd()shutil.copyfile('data.db', 'archive.db')shutil.move('/build/executables', 'installdir')shutil.rmtree("./test_dir")print(glob.glob('*.py')) # ['primes.py', 'random.py', 'quote.py']
执行语句
eval(source, globals=None, locals=None, /)
或者
exec(source, globals=None, locals=None, /)
globals 和locals传字典类型, globals不传会使用默认全局命名空间eval会返回执行结果, exec不会
执行shell命令
sys.call()subprocess.Popen()
正则表达式
参考菜鸟教程
数据库
内置了
sqlite3使用
mysql, 用pymysql或者mysql-connector库
网络
- socket: 直接
import socket使用即可,包含服务端和客户端 - http客户端: requests(入门推荐), urllib, httplib, xmlrpclib, 解析用
xpath或BeautifulSoup
多线程
- 简单的用
_thread模块
_thread.start_new_thread ( function, args[, kwargs] )
参数
- function - 线程函数。
- args - 传递给线程函数的参数,他必须是个tuple类型。
- kwargs - 可选参数。
推荐用
threading模块同步锁用
threading.Lock()和threading.RLock()(同一个线程可重入可嵌套)多线程使用队列, 可以直接使用
queue模块
多进程
- unix 下可以用
os.fork - 跨平台使用
multiprocessing模块 - 调用执行其它程序用
subprocess - 还可以使用
multiprocessing.managers模块来分布式进程
参考这里
协程
def consumer():r = ''while True:n = yield rif not n:returnprint('[CONSUMER] Consuming %s...' % n)r = '200 OK'def produce(c):c.send(None)n = 0while n < 5:n = n + 1print('[PRODUCER] Producing %s...' % n)r = c.send(n)print('[PRODUCER] Consumer return: %s' % r)c.close()c = consumer()produce(c)
asyncio 实现异步IO
import threadingimport asyncio@asyncio.coroutinedef hello():print('Hello world! (%s)' % threading.currentThread())yield from asyncio.sleep(1)print('Hello again! (%s)' % threading.currentThread())async def hello2():print("Hello world!")r = await asyncio.sleep(1)print("Hello again!")loop = asyncio.get_event_loop()tasks = [hello(), hello2()]loop.run_until_complete(asyncio.wait(tasks))loop.close()
json
json.loads,json.dumps用来处理json字符串和dict互相转换json.load,json.dump用来处理文件中的json字符串和dict互相转换,参数需要传文件操作对象
常见问题以及遇到的问题
bytes 和 str 不同
dataToSend = 'AT\r\n'self.com.write(dataToSend)
raise TypeError('unicode strings are not supported, please encode to bytes: {!r}'.format(seq))
解决:
dataToSend = 'AT\r\n'.encode()print(dataToSend)self.com.write(dataToSend)
打包 cx-freeze
bash: /c/Users/neucrack/AppData/Local/Programs/Python/Python36-32/Scripts/cxfreeze: C:\program: bad interpreter: No such file or directory
解决:C:\Users\neucrack\AppData\Local\Programs\Python\Python36-32\Scripts下的cxfreeze和cxfreeze-postinstall和cxfreeze-quickstart文件修改一下:
#!python.exe
cx-freeze打包去掉控制台黑框
如果是windows,加一个参数
--base-name=win32gui
或者使用cxsetup.py配置文件,base = "Win32GUI"
pyqt使用styleSheet
# 对整个app生效:app = QApplication(sys.argv)file = open('style.qss',"r")app.setStyleSheet(file.read())# 对单个组件生效:button = ...button.setStyleSheet(file.read())
例子见官方文档

