本文最后更新于2021年02月15日;如遇问题,请留言及时通知站长。

macOS Python 环境配置

强烈建议使用 Anacondahttps://www.anaconda.com/),Windows、Linux、Mac都有相应版本,而且安装包管理起来比较方便;

不过 Anaconda 更新起来比较慢,建议换成国内镜像源;

安装完 Anaconda 后,如果终端窗口 conda 命令不能运行,可以先配置 .zshrc 文件;

打开终端,输入: vi ~/.zshrc 之后回车,然后按字母 i 进入插入编辑模式,输入下列代码: export PATH=/opt/anaconda3/bin:$PATH ,其中红色字体要替换成你自己电脑上的conda所在目录,按 ESC 键,输入: :wq 三个字符,文件被保存后退出。终端再输入:source ~/.zshrc ,使其立即生效,这时就可以用: conda --version ,查看 conda 的版本信息。

安装 OpenCV

打开终端,输入: sudo pip3 install opencv-python ,按提示输入密码,之后就是漫长的安装过程。

切换成国内镜像源会非常快:
sudo pip3 install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple

直接运行 py 文件

.py 文件在Windows上是不能像exe文件直接执行的。但是,在Mac和Linux上是可以的,方法是在.py文件的第一行加上一个特殊的注释:

#!/usr/bin/env python3
print('hello, world')

然后,通过命令给 hello.py 以执行权限:$ chmod a+x hello.py

,就可以直接运行 hello.py 了,执行:Air:~ sirit$ ./hello.py

print() 输出字符串

print()函数可接受多个字符串,用逗号“,”隔开,就可以连成一串输出,print()会依次打印每个字符串,遇到逗号“,”会输出一个空格
name = input('please enter your name: ')
print('hello,', name)

Python 基础

Python的语法采用缩进方式,应该始终坚持使用4个空格的缩进。Python程序是大小写敏感的。
#开头的语句是注释。
Python3 的六个标准数据类型中:

  • 不可变数据(3 个):Number(数字)、String(字符串)、Tuple(元组);
  • 可变数据(3 个):List(列表)、Dictionary(字典)、Set(集合)。
    整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的误差。

字符串是以单引号'或双引号"括起来的任意文本。
转义字符\可以转义很多字符,比如\n表示换行,\t表示制表符,字符\本身也要转义,所以\\表示的字符就是\。Python用r''表示''内部的字符串默认不转义。
在Python中,可以直接用True、False表示布尔值(请注意大小写)。
空值是Python里一个特殊的值,用None表示。
变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。
在Python中,通常用全部大写的变量名表示常量。
Python的整数没有大小限制,而某些语言的整数根据其存储长度是有大小限制的,例如Java对32位整数的范围限制在-2147483648-2147483647。Python的浮点数也没有大小限制,但是超出一定范围就直接表示为inf(无限大)。
list [ ] 是一种有序的集合,可以随时添加和删除其中的元素。
另一种有序列表叫元组:tuple ( )。tuple ( ) 和 list [ ]非常类似,但是 tuple 一旦初始化就不能修改。

条件判断

条件判断从上向下匹配,当满足条件时执行对应的块内语句,后续的elif和else都不再执行。

使用dict和set

请务必注意,dict内部存放的顺序和key放入的顺序是没有关系的。
和list比较,dict有以下几个特点:

  • 查找和插入的速度极快,不会随着key的增加而变慢;
  • 需要占用大量的内存,内存浪费多。

而list相反:

  • 查找和插入的时间随着元素的增加而增加;
  • 占用空间小,浪费内存很少。

所以,dict是用空间来换取时间的一种方法。
dict可以用在需要高速查找的很多地方,在Python代码中几乎无处不在,正确使用dict非常重要,需要牢记的第一条就是dict的key必须是不可变对象。这是因为dict根据key来计算value的存储位置,如果每次计算相同的key得出的结果不同,那dict内部就完全混乱了。这个通过key计算位置的算法称为哈希算法(Hash)。要保证hash的正确性,作为key的对象就不能变。在Python中,字符串、整数等都是不可变的,因此,可以放心地作为key。而list是可变的,就不能作为key。
set可以看成数学意义上的无序和无重复元素的集合,set和dict的唯一区别仅在于没有存储对应的value。

函数

函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”。
在Python中,定义一个函数要使用def语句,依次写出函数名、括号、括号中的参数和冒号:,然后,在缩进块中编写函数体,函数的返回值用return语句返回。
空函数:如果想定义一个什么事也不做的空函数,可以用pass语句。
定义函数时,需要确定函数名和参数个数;如果有必要,可以先对参数的数据类型做检查;函数体内部可以用return随时返回函数结果;函数执行完毕也没有return语句时,自动return None。函数可以同时返回多个值,但其实就是一个tuple。
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
李笑来《the-craft-of-selfteaching》(Part.2.D.2-aargs.ipynb)面对许多参数,Python 需要按照既定的规则(即,顺序)判定每个参数究竟是哪一类型的参数:

Order of Arguments
1.Positional
2.Arbitrary Positional
3.Keyword
4.Arbitrary Keyword

Python的函数具有非常灵活的参数形态,既可以实现简单的调用,又可以传入非常复杂的参数。默认参数一定要用不可变对象,如果是可变对象,程序运行时会有逻辑错误!
要注意定义可变参数和关键字参数的语法:

  • *args是可变参数,args接收的是一个tuple;
  • **kw是关键字参数,kw接收的是一个dict。

以及调用函数时如何传入可变参数和关键字参数的语法:

  • 可变参数既可以直接传入:func(1, 2, 3),又可以先组装list或tuple,再通过args传入:func((1, 2, 3));
  • 关键字参数既可以直接传入:func(a=1, b=2),又可以先组装dict,再通过kw传入:func({'a': 1, 'b': 2})。

使用 *args 和 **kw 是Python的习惯写法,当然也可以用其他参数名,但最好使用习惯用法。
命名的关键字参数是为了限制调用者可以传入的参数名,同时可以提供默认值。
定义命名的关键字参数在没有可变参数的情况下不要忘了写分隔符' *,',否则定义的将是位置参数。
使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。针对尾递归优化的语言可以通过尾递归防止栈溢出。

高级特性

切片
默认情况下,dict迭代的是key。 >>> isinstance('abc', Iterable) # str是否可迭代
Python内置的 enumerate 函数可以把一个list变成索引-元素对。
在一个列表生成式中,for 前面的 if ... else 是表达式,而 for 后面的 if 是过滤条件,不能带 else。
要创建一个 generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的 [] 改成 (),就创建了一个 generator。如果一个函数定义中包含 yield 关键字,那么这个函数就不再是一个普通函数,而是一个 generator。
凡是可作用于for循环的对象都是Iterable类型;
凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
Python的for循环本质上就是通过不断调用next()函数实现的。

函数式编程

函数本身也可以赋值给变量,即:变量可以指向函数。把函数作为参数传入,这样的函数称为高阶函数,函数式编程就是指这种高度抽象的编程范式。
map() 函数接收两个参数,一个是函数,一个是 Iterable, map 将传入的函数依次作用到序列的每个元素,并把结果作为新的 Iterator 返回。
reduce 把一个函数作用在一个序列 [x1, x2, x3, ...] 上,这个函数必须接收两个参数,reduce 把结果继续和序列的下一个元素做累积计算。
Python内建的 filter() 函数用于过滤序列。filter() 也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是 True 还是 False 决定保留还是丢弃该元素。
Python内置的 sorted() 函数就可以对 list 进行排序。它还可以接收一个 key 函数来实现自定义的排序,要进行反向排序,不必改动key函数,可以传入第三个参数 reverse=True。
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
关键字 lambda 表示匿名函数,冒号前面的 x 表示函数参数。匿名函数有个限制,就是只能有一个表达式,不用写 return ,返回值就是该表达式的结果。
在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)
简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

模块

在 Python 中,一个.py文件就称之为一个模块(Module)。使用模块可以避免函数名和变量名冲突。
为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。请注意,每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany。
类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用。
在Python中,安装第三方模块,是通过包管理工具pip完成的。

面向对象编程

注:本文为在 廖雪峰的官方网站 学习Python3的学习笔记。

文章目录