选中内容(绿色)时除了会搜索文章名,还会搜索文章内容
点击结果中的文章名进入文章界面后可以按Ctrl+F在页面内搜索
  • 版权:CC BY-SA 4.0
  • 创建:2019-10-13
  • 更新:2020-10-10
一文python从入门到放弃, 如果你有其它一门面向对象语言(比如C++/Java/JS)基础,看了应该就会了


本文主要是简单介绍,具体大量的函数库的使用不会具体说明, 比如对于list类型会简单介绍概念,具体它相关的方法需要看文档或者其它更详细的教程

简介

Python 是一种解释型、面向对象、动态数据类型的高级程序设计语言
python, 英文翻译为蟒蛇, 也可以看到它的 logo 也是两条不同颜色的蛇
1991年发行, 创始人为荷兰人吉多·范罗苏姆(Guido van Rossum)
python的实现也有很多版本, 主要使用的是python.org的版本(也就是CPython), 到现在实现分别有python2python3两个大版本

特征

  • 跨平台脚本语言
  • 不需要编译, 解释型语言,语法检查也是在运行时
  • 使用缩进符号来作为域分隔,作用类似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中默认已经安装了, 命令是python3python命令默认可能是python2), 以下均用python表示python3, 除非特殊说明

  • 运行程序, 比如取名soft.py

    1. print("hello python")

    直接使用python soft.py即可运行软件soft.py。

  • 如果不支持中文, 可以设置一下系统语言(unix)

  1. export LC_ALL=C.UTF-8
  2. export LANG=C.UTF-8

加入到~/.bashrc或者~/.zshrc

寻找库


发布

  • 源码直接发布, 比如我写的这个串口助手

  • 二进制发布,打包成平台对应的可执行文件, 比如 windows 的 exe, macOS 的 dmg
    使用py2exe、cx-freeze、pyInstaller(推荐)等工具来进行打包,这种打包方式会将环境和依赖一同打包进软件,用户使用时下载软件包后可以直接运行,不需要用户自己安装Python。
    比如cx-free打包:参考:http://www.cnblogs.com/zhongtang/p/5699322.html
    建议使用pyinstaller, 比如

    1. 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就可以安装软件啦

虚拟环境

  • 如果需要对某个工程使用特定的环境,使用virtualenv
    1. pip3 install virtualenv
    2. virtualenv --no-site-packages venv # venv是虚拟环境的名称
    3. source venv/bin/activate #激活虚拟环境
    4. deactivate # 退出虚拟环境
  • 如果需要在一台电脑上安装多个环境(不同python版本,同时还可以不同包),可以用conda(miniconda(推荐), Anaconda都可以)
    1. conda create --name test python=3.7
    2. conda activate test #激活环境
    3. conda list # 展示已经安装了的包
    4. conda deactivate # 退出环境

基本语法

查看模块帮助信息

  1. import json
  2. print(dir(json))
  3. help(json)

打印

  1. print("hello")
  2. print("hello", "no return" , end="")
  3. print("hello")

注释

  • 行注释: #开头
  • 段注释: 三引号
    1. #############
    2. # 这是注释
    3. #############
    4. '''
    5. 这也是注释
    6. '''
    7. """
    8. 这也是注释
    9. """

另外,在文件头声明

  1. #! /usr/bin/env python3

可以使用./文件名.py直接执行

缩进

这是python 和其它语言非常不同的一点, 其它语言很多都用大括号来分隔函数条件循环等, python使用缩进, 可以使用tab或者空格, 所以这里也需要十分注意,tab和空格是不一样的,在写程序时需要使用一样的,最好编辑器设置好tab自动转换为4个空格

  1. def func():
  2. print("hello") # 这里使用了tab按键
  1. def func2():
  2. print("hello") # 这里使用了空格

注意如果在一个文件内即用空格又用tab就会报格式错误

多行

和其它语言一样使用\ 符号来换行, 如果是list, dict等对象,不需要,比如:

  1. a = [1,2,
  2. 3,4]
  3. b = {
  4. "aaa": 123
  5. }

等待用户输入

  1. a = input("请输入内容")
  2. print(a)

同一行多个语句

  1. print("aaa"); print("bbb")

变量

直接赋值,不需要声明类型

  1. a = 10
  2. print(type(a))
  3. print(a)

注意 全局变量使用

  • 全局变量在函数中使用需要注意:获取值可以直接使用,但是如果要赋值一定要 global 声明, 不然是定义一个新的局部变量
  1. g = 10
  2. def test():
  3. print(g)
  4. def test2():
  5. g = 20
  6. def test3():
  7. global g
  8. g = 30
  9. print(test())
  10. print(test2())
  11. print(g)
  12. print(test3())
  13. print(g)
  • nonlocal 使用
  1. def outer():
  2. num = 10
  3. def inner():
  4. nonlocal num # nonlocal关键字声明
  5. num = 100
  6. print(num)
  7. inner()
  8. print(num)
  9. outer()

类型

可以用type(变量)来获取变量类型

str: 字符串, bytes:字节

字符串可以用单引号或者双引号或者三引号, 可以嵌套, 比如'string:"hello"', 不需要转义符,很方便。
三引号是可以扩一整段,包括多行,注意不赋值给变量可以当成注释功能

  • python 里面字符串分为两种, 一个是ascii字节码, 另一个unicode字符串

    1. str_bytes = b'12\xe5\x93\x88\xe5\x93\x88\xe5\x93\x88\xe5\x93\x88'
    2. str_unicode = '12哈哈哈哈'
    3. print(str_unicode.encode('utf-8') == str_bytes)
    4. print(str_unicode == str_bytes.decode())
  • 字串: 下标取,

  • 字符串的常见函数,直接在终端中输入变量按tab补全就有了, 或者看文档
    这里说一下格式化字符串:
    第一种,类似cprintf

    1. my_str = 'hello %.2f %04d %s' %(1.23456, 12, "good")
    2. print(my_str)

    或者format

    1. my_str = 'hello {:.2f} {:04d} {}'.format(1.23456, 12, "good")
    2. print(my_str)
  • 转义符号:\,如果不想字符串被转义,在字符串前面添加r,比如`r’hello\n’’

  • 去掉行末空格 行首空格

    1. s = ' 123 '
    2. print(s.strip())
    3. print(s.lstrip())
    4. print(s.rstrip())

list: 列表, 类似 C 中的数组

  1. a = [1,2,3,4, "hello"]
  • 取子list
  1. a = [1,2,3,4,5]
  2. 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()。

  1. list=[1,2,3,4]
  2. it = iter(list) # 创建迭代器对象
  3. for x in it:
  4. print (x, end=" ")

tuple:元组, 不可更改

  1. a = (1,2,3,4, "hello")

set, frozenset: 与数学中集合的概念类似。无序的、每个元素唯一。

  1. {4.0, 'string', True}
  2. frozenset([4.0, 'string', True])

dict: 字典, 键值对

  1. d = {
  2. 'key1': 1.0,
  3. 3: False
  4. }
  5. print(d)

int, floatbool:证书浮点数布尔

  1. a = 10
  2. b = 1.234
  3. print(a, b, int(b))
  4. a = True
  5. b = False

注意 True``False大写开头

complex: 复数

  1. 3+2.7j

range: 按顺序排列的数

  1. a = range(10)
  2. a = range(0, 10)
  3. print(list(a))

运算符

几乎和其它语言一样, +-*/, <<, >> | &, 或是or, 与是and, 非是not

  1. a = 10
  2. if not 0 and a==10:
  3. 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): 将一个整数转换为一个八进制字符串

函数

  1. def test(arg, optional=10):
  2. print(arg, optional)
  3. test()

  1. class Base:
  2. a = 10
  3. b = 20
  4. __private_v = 10
  5. class AAA(Base):
  6. def __init__(self, arg):
  7. print(arg)
  8. print(a)
  9. def __del__(self):
  10. pass
  11. varA = AAA(123)
  12. print(varA.a, varB.b, AAA.a, AAA.b)
  13. varA.a = 100
  14. AAA.a = 999
  15. AAA.b = 888
  16. print(varA.a, varB.b, AAA.a, AAA.b)
  • 需要注意的类的变量的对象的变量, 对象的变量要在构造函数__init__中使用self.a这样定义,
    类变量要直接在类中定义,就像上面Base类的a变量。
    每个对象都会有这个类变量,但是对象一旦修改了这个类变量,这个类变量就变成了这个对象专有的对象变量了,通过类名修改这个变量也不会影响到这个对象变量

  • 注意,这里每个成员函数的self参数就是对象, 不是类, 类成员用类名调用

  • __两个下划线开头表示是私有变量

  • 调用父类方法: super(Class, obj).func()

  • 返回多个参数: 返回一个元组或者列表类型即可

  • 匿名函数lambda:

    1. add = lambda x,y:x+y
    2. print(add(3,4))
  • 闭包函数(返回函数)

    1. #闭包函数,其中 exponent 称为自由变量
    2. def nth_power(exponent):
    3. def exponent_of(base):
    4. return base ** exponent
    5. return exponent_of # 返回值是 exponent_of 函数
    6. square = nth_power(2) # 计算一个数的平方
    7. cube = nth_power(3) # 计算一个数的立方
    8. print(square(2)) # 计算 2 的平方
    9. print(cube(2)) # 计算 2 的立方
  • 函数注解(decorator)
    本质上,decorator就是一个返回函数的高阶函数.

    1. def log(func):
    2. def wrapper(*args, **kw):
    3. print('call %s()' % func.__name__)
    4. return func(*args, **kw)
    5. return wrapper
    6. @log
    7. def now():
    8. print('2015-3-25')
    9. #call now()
    10. #2015-3-25
  • 偏函数

  1. from functools import partial
  2. def mod( n, m ):
  3. return n % m
  4. mod_by_100 = partial( mod, 100 )
  5. print mod( 100, 7 ) # 2
  6. print mod_by_100( 7 ) # 2
  7. bin2dec = partial( int, base=2 )
  8. print bin2dec( '0b10001' ) # 17
  9. print bin2dec( '10001' ) # 17
  • 参数,返回值类型指定:
    1. def add(num1: int, num2: int=100) -> int:
    2. sum = num1 + num2
    3. return sum
    4. #
    5. if __name__ == "__main__":
    6. print(add.__annotations__)
    7. print(add(1,2))
    8. print(add(1))
    9. print(add('test1', 'test2'))
    输出为:
    1. {'num1': <class 'int'>, 'num2': <class 'int'>, 'return': <class 'int'>}
    2. 3
    3. 101
    4. test1test2

控制语句

  • if:

    1. a = 1
    2. if a == 1:
    3. print("hello")
    4. elif a == 2:
    5. print("hello 2")
    6. else:
    7. print("hello 3")
  • for:循环迭代器

    1. for i in range(0, 10):
    2. print(i)
    3. `
  • while:循环

    1. count = 0
    2. while 1:
    3. print("hello")
    4. count += 1
    5. if count < 2:
    6. continue
    7. break
  • try:捕获

    1. import traceback
    2. import sys
    3. try:
    4. raise Exception("error lalala")
    5. except Exception as e:
    6. print("error:", e)
    7. traceback.print_exc()
    8. err_info2 = sys.exc_info()
    9. traceback.print_tb(err_info2[2])
    10. else:
    11. print("no error")
    12. finally:
    13. print("finally")

    这里用了 traceback.print_exc()或者sys.exc_info() 来打印出错的行数等信息
    traceback.print_exc()原型是print_exception(etype, value, tb[,limit[, file]])

  • pass: 表示此行为空,不运行任何操作。

  • assert: 用于程序调试阶段时测试运行条件是否满足。

  • with:

    1. with open("file.txt") as f:
    2. print(f.read())
  • yield: 在迭代器函数内使用,用于返回一个元素。自从Python 2.5版本以后。这个语句变成一个运算符。

  • in: 判断一个对象是否在一个字符串/列表/元组里。

    1. for i in range(0, 10):
    2. print(i)
    3. l = [1,2,3]
    4. print(2 in l)
  • import: 导入一个模块或包。

  • from … import: 语句,从包导入模块或从模块导入某个对象。
  • import … as: 语句,将导入的对象赋值给一个变量(别名)。

常用全局变量

  • __name__: 当文件或模块被python直接执行比如python test.py 则这个文件这个变量的值为__main__,否则为包名, 所以可以利用这个来区分是被当成模块调用还是直接执行, 一般在文件中写:

    1. def test():
    2. print("test")
    3. if __name__ == "__main__":
    4. test()
  • __file__: 当前文件的路径, 注意以相对路径运行文件可能是相对路径, 可以用os.path.abspath(__file__)获取绝对路径

  • __all__: 指定模块内哪些变量能被import使用

  1. def test():
  2. print("hello")
  3. def test2():
  4. print("test2")
  5. __all__ = ['test'] # 如果使用 from var import test2 会报错
  6. # 但是使用import var; var.test2()可以使用
  7. # 直接执行文件也是都可以访问的

模块

一个模块是一个文件夹, 下面有一个__init__.py, 这里面的内容就是模块的内容, 也可以在文件夹下建其它文件

  1. test
  2. ├─ __init__.py
  3. ├─ aaa.py
  4. └─ bbb.py

使用:

  1. import test
  2. from test import aaa, bbb
  3. from test.aaa import *

常见模块及使用方法

后台运行及时打印日志到文件

执行命令时加 -u 参数,

  1. (python -u test.py > teset.log 2>&1 &)

文件操作

  1. with open("文件名", 'r') as f:
  2. print(f.read())
  1. f = open("文件名", 'r')
  2. print(f.read())
  3. f.close()

更多可以看其它教程

文件、文件夹、路径操作

  1. import sys
  2. import os
  3. import shutil
  4. import glob
  5. os.getcwd()
  6. shutil.copyfile('data.db', 'archive.db')
  7. shutil.move('/build/executables', 'installdir')
  8. shutil.rmtree("./test_dir")
  9. print(glob.glob('*.py')) # ['primes.py', 'random.py', 'quote.py']

执行语句

  1. eval(source, globals=None, locals=None, /)

或者

  1. exec(source, globals=None, locals=None, /)

globalslocals传字典类型, globals不传会使用默认全局命名空间
eval会返回执行结果, exec不会

执行shell命令

  1. sys.call()
  2. subprocess.Popen()

正则表达式

参考菜鸟教程

数据库

  • 内置了sqlite3

  • 使用 mysql, 用pymysql 或者 mysql-connector

网络

  • socket: 直接 import socket 使用即可,包含服务端和客户端
  • http客户端: requests(入门推荐), urllib, httplib, xmlrpclib, 解析用xpathBeautifulSoup

多线程

  • 简单的用_thread模块
  1. _thread.start_new_thread ( function, args[, kwargs] )

参数

  • function - 线程函数。
  • args - 传递给线程函数的参数,他必须是个tuple类型。
  • kwargs - 可选参数。
  • 推荐用threading 模块

  • 同步锁用threading.Lock()threading.RLock()(同一个线程可重入可嵌套)

  • 多线程使用队列, 可以直接使用queue模块

多进程

  • unix 下可以用os.fork
  • 跨平台使用multiprocessing模块
  • 调用执行其它程序用subprocess
  • 还可以使用multiprocessing.managers模块来分布式进程

参考这里

协程

  1. def consumer():
  2. r = ''
  3. while True:
  4. n = yield r
  5. if not n:
  6. return
  7. print('[CONSUMER] Consuming %s...' % n)
  8. r = '200 OK'
  9. def produce(c):
  10. c.send(None)
  11. n = 0
  12. while n < 5:
  13. n = n + 1
  14. print('[PRODUCER] Producing %s...' % n)
  15. r = c.send(n)
  16. print('[PRODUCER] Consumer return: %s' % r)
  17. c.close()
  18. c = consumer()
  19. produce(c)

asyncio 实现异步IO

  1. import threading
  2. import asyncio
  3. @asyncio.coroutine
  4. def hello():
  5. print('Hello world! (%s)' % threading.currentThread())
  6. yield from asyncio.sleep(1)
  7. print('Hello again! (%s)' % threading.currentThread())
  8. async def hello2():
  9. print("Hello world!")
  10. r = await asyncio.sleep(1)
  11. print("Hello again!")
  12. loop = asyncio.get_event_loop()
  13. tasks = [hello(), hello2()]
  14. loop.run_until_complete(asyncio.wait(tasks))
  15. loop.close()

json

  • json.loads, json.dumps用来处理 json字符串dict 互相转换
  • json.load, json.dump用来处理 文件中的json字符串dict 互相转换,参数需要传文件操作对象

常见问题以及遇到的问题

bytes 和 str 不同

  1. dataToSend = 'AT\r\n'
  2. self.com.write(dataToSend)
  1. raise TypeError('unicode strings are not supported, please encode to bytes: {!r}'.format(seq))

解决:

  1. dataToSend = 'AT\r\n'.encode()
  2. print(dataToSend)
  3. self.com.write(dataToSend)

打包 cx-freeze

  1. 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文件修改一下:

  1. #!python.exe

cx-freeze打包去掉控制台黑框

如果是windows,加一个参数

  1. --base-name=win32gui

或者使用cxsetup.py配置文件,base = "Win32GUI"

pyqt使用styleSheet

  1. # 对整个app生效:
  2. app = QApplication(sys.argv)
  3. file = open('style.qss',"r")
  4. app.setStyleSheet(file.read())
  5. # 对单个组件生效:
  6. button = ...
  7. button.setStyleSheet(file.read())

例子见官方文档

参考

文章有误?有想法想讨论?查看或者发起勘误/讨论 主题
(发起评论需要先登录 github)

/wallpaper/wallhaven-391r1d.jpg