Py学习  »  Python

Python 入门

任沫 • 2 年前 • 262 次点击  
阅读 61

Python 入门

本文主要根据Python官网教程(该网站左上角有选项可切换中文)进行入门学习,是一个对该文档中知识点的总结和练习,只是整体地简单了解下几个知识点。

安装

首先安装Python,可以选择以下两种方式中的一种:

方式一,使用brew:

1、安装python3,如果需要使用特定的版本,可以用brew install python@3.7

brew install python3
复制代码

之后可以使用 brew info python3查看包信息。

2、创建链接:

brew link python3
复制代码

创建链接的时候我遇到了链接已存在的报错,根据提示内容使用以下这句覆盖所有的配置文件:

 brew link --overwrite python@3.8
复制代码

3、将环境变量添加到~/.zshrc文件中:

echo 'export PATH="/usr/local/opt/python@3.8/bin:$PATH"' >> ~/.zshrc
复制代码

重新执行一下~/.zshrc文件:

source r ~/.zshrc
复制代码

在终端输入python3 --version测试下,已经变成新安装的Python 3.8.4了。

  1. 设置python别名

Mac操作系统本身安装了Python,版本为2.7.15。所以使用pythonpython3的时候,分别使用的是版本2和3,如果不想一直输入python3,设置下别名就行了。注意不要尝试去修改系统自带的Python2,一般不会操作成功,假如操作成功了,也可能会导致一些系统问题。

➜  ~ python --version
Python 2.7.15
➜  ~ python3 --version
Python 3.8.4
复制代码

设置pythonpip的别名分别为python3pip3pip是Python用来安装/发布包(packages)的指令。

echo 'alias python=python3 \n alias pip=pip3' >> ~/.zshrc
复制代码

重新执行下~/.zshrc文件:

source ~/.zshrc
复制代码

重新执行下python --version就能看到已经是版本3了。

方式二,下载安装包:

Python下载地址选择需要的Python版本进行下载,下载安装包后,点击安装包文件,根据界面提示一步步进行安装即可。

================安装Python开发工具================

下载好Python之后需要安装一下Python的开发工具,因为我一直用的是VSCode,所以我直接在VSCode上安装了Python插件,这个在VSCode里面的插件里输入Python一搜就出来了。有几个便于Python开发的VSCode设置可以了解一下。

使用Python解释器

有各种可以使用Python解释器的方式,详情可以看命令行和环境

1.在终端输入python就可以运行Python解释器了。键入Control + D或者输入quit()退出解释器。

$ python 
Python 3.8.4 (default, Jul 14 2020, 01:57:59) 
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = '1'
>>> if a:
...     print(a)
... 
1
>>> quit()
$
复制代码

在命令行中有>>>提示符的就是交互模式,在有多行的情况下会出现...提示符。

2.在python后面使用文件名,会读取并执行该脚本文件。

已经有一个python文件a.py,内容如下:

a = '1'
if a:
    print(a)
复制代码

在终端执行:

$ python a.py
1
复制代码

如果说执行了脚本文件之后想要进入交互模式,在脚本前面加上-i就可以了。

$ python -i a.py
1
>>> 
复制代码

3.在python后面使用目录名,会从该目录读取并执行合适的脚本。

文件路径是这样的,a文件夹下包含一个__main__.py文件:

├── a
│   └── __main__.py
复制代码

__main__.py文件的内容是:

a = '2'
if a:
    print(a)
复制代码

在终端执行:

$ python a
2
复制代码

4.使用python -c command [arg] ...在命令行中执行语句。

$ python -c 'print("a")'
a
复制代码

5.使用python -m module [arg] ...执行模块(module)的源文件。

b.py文件内容如下:

# 这是一个模块,如果是以`python b.py`的方式执行,就会把全局变量赋值为`'__main__'`
# 脚本名称以及后面的参数会被转化为一个字符串列表,被赋值给`sys`模块中的`argv`变量。`sys.argv[0]`是表示程序来源的字符串。
# python中的注释以井号`#`开头
import sys
print(sys.argv[0])

if __name__ == '__main__':
    print('b')
else:
    print('b1')
复制代码

执行python -m b

$ python -m b
/Users/.../python_code/b.py
b
复制代码

执行python b.py

$ python b.py
b.py
b
复制代码

在之前的a.py文件的开头加上import b导入模块b

执行python a.py

$ python a.py
a.py
b1
1
复制代码

6.也可以点击VSCode编辑器右上角的三角形的运行按钮来执行文件,但是我目前一般没用这个。

数据结构

数字

整数的类型是 int,有小数部分的数字的类型是 float(浮点数)。

可以使用数字和操作符进行一些计算,有以下操作:

操作结果
x + yxy的和
x - yxy的差
x * yxy的乘积
x / yxy的商,这个结果永远是浮点数
x // yxy的商数,xy的商向下四舍五入
x % yx / y的余数
-xx的负数
+xx保持不变
abs(x)x的绝对值
int(x)x转换为整数
float(x)x转换为浮点数
complex(re, im)实部为re,虚部为im的复数,im默认为0。
c.conjugate()复数c的共轭
divmod(x, y)(x // y, x % y)
pow(x, y)xy次幂
x ** yxy次幂

除了 intfloat,Python还支持 DecimalFraction类型的数字. Python也有一些对复数的内建支持 complex numbers,使用j或者J表示虚数的部分。

在交互模式下,最后一个被打印的表达式会被赋值给_

>>> 1 + 2
3
>>> 1 // 2
0
>>> 1 % 2
1
>>> 5 ** 2
25
>>> _
25
复制代码

字符串

1.字符串被单引号'' 或者双引号""包裹。

>>> "aaa" == 'aaa'True
复制代码

2.反斜线\可以用来转译引号。在原始字符号的引号前面加上一个r能防止\被解析为特殊符号。

>>> 'a\'aa'
"a'aa"
>>> r'a\'aa'
"a\\'aa"
>>> print(r'a\'aa')
a\'aa
复制代码

print() 函数给出一个更可读的输出。去掉了包裹的引号,打印的是转译之后的字符串。

3.可以使用三引号''' / """来包裹多行字符串。行尾会自动添加到字符串中,使用\来防止这种情况。

>>> a = '''\
... 第一行
... 第二行\
... '''
>>> print(a)
第一行
第二行
>>> 
复制代码

这里要注意的是当我们输入'''之后,出现了...的提示符,这种时候一定要把结尾的'''输完,才能够重新进入>>>

4.使用+连接字符串,* 号重复字符串。

>>> 'a' + 'b'
'ab'
>>> 2 * 'a' + 'b'
'aab'
复制代码

5.字符串可以被索引。负索引从-1开始。

>>> a = 'abcdefg'
>>> a[1]
'b'
>>> a[-1]
'g'
复制代码

6.字符串可以被切片。s[i:j]会取字符串s的包含索引i到索引j - 1部分的字符。第一个位置索引被忽略就默认为0,第二个索引被忽略就默认为整个字符串的长度。

>>> a[:2]
'ab'
>>> a[2:]



    
'cdefg'
>>> a[2: 5]
'cde'
复制代码

7.格式化字符串字面量。在引号前面加上fF,在字符串内使用{}包裹表达式。

>>> f'String a is "{a}"'
'String a is "abcdefg"'
复制代码

8.内置 len()函数返回字符串的长度。

>>> len(a)
7
复制代码

9.字符串是不可变的( immutable),它不能被修改。

>>> a[0] = 'A'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> 
复制代码

列表

1.列表是使用[]包裹、,分隔的一组值。列表可以包含不同类型的元素。

>>> a = [1, 2, '3']
复制代码

2.内置序列类型( liststrtuplebytes)可以被索引和切片。

>>> a = [1, 2, '3', 'a', 'b', 'c']
>>> a[2]
'3'
>>> a[2: 5]
['3', 'a', 'b']
复制代码

3.len() 返回列表元素的数量。

>>> len(a)
6
复制代码

4.列表可以合并。

>>> b = ['d']
>>> a + b
[1, 2, '3', 'a', 'b', 'c', 'd']
复制代码

5.列表是可变的( mutable ),它可以被修改。

>>> a = [1, 2, '3', 'a', 'b', 'c']
>>> a[2:6] = []
>>> a
[1, 2]
复制代码

6.列表可以嵌套。

>>> [a, 'x', 'y']
[[1, 2], 'x', 'y']
复制代码

列表的方法

方法描述
list.append(x)添加一项到列表的末尾。和 a[len(a):] = [x]等价。
list.extend(iterable)通过将可迭代对象的每一项添加到列表中扩展列表。等价于 a[len(a):] = iterable
list.insert(i, x)在给定的位置插入一项。第一个参数是在被插入元素之前的元素的索引,所以a.insert(0, x)在列表的前面添加一个元素,并且a.insert(len(a), x)a.append(x)等价。
list.remove(x)移除列表中值为x的第一项。在没有这样一项的时候,会抛出一个值错误 ValueError
list.pop([*i*])移除列表中给定位置的项,并且返回它。如果没有声明indexlist.pop()会移除并且返回列表的最后一项。(包围着i的方括号表明这个参数是可选的,不是你需要在这个位置打出方括号)
list.clear()移除列表中所有的项。等价于 del a[:]
list.index(x[, start[, end]])返回列表中值为x的从0开始的索引。如果没有这样的项的时候,会抛出一个ValueError 。可选的参数startend被用来限制在列表的特定的子序列进行搜索。返回的索引是相对整个序列的开始的,而不是相对于start参数开始。
list.count(x)返回出现在列表中的x项的数量。
list.sort(*, key=None, reverse=False)对列表中的项目进行排序。sorted()
list.reverse()按位置反转列表的元素。
list.copy()返回一个列表的浅复制。等价于 a[:]

del 语句

使用 del语句可以使用一个项的索引来送列表中删除该项,而不是使用它的值来删除它。del声明还可以从列表中移除切片或者清除整一个列表。del 还可以用来删除整个变量。

>>> a = [1, 2, 3, 4, 5]
>>> del a[0]
>>> a
[2, 3, 4, 5]
>>> del a[0:1]
>>> a
[3, 4, 5]
>>> del a[:]
>>> a
[]
>>> del a
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> 
复制代码

元组

一个元组由被逗号分隔的一些值组成。元组是不可变的( immutable)。

>>> t = 1, 2, 3
>>> x, y, z = t
>>> print(x, y, z)
1 2 3
>>> empty = ()
>>> singleton = 'a',
>>> a = (1, 2, [1, 2])
>>> a[0]
1
>>> len(a)
3
复制代码

集合

一个集合(set)是一个没有重复元素的无序集(collection)。

>>> a = 'abccc'
>>> b = set(a)
>>> b
{'a', 'c', 'b'}
>>> c = set() # 空集合
>>> b - c # 在b中存在,c中不存在的元素
{'a', 'c', 'b'}
>>> c = set('dee')
>>> c
{'e', 'd'}
>>> b | c # 在b中或者在c中的元素
{'a', 'c', 'e', 'b', 'd'}
>>> b & c # 在b中并且也在c中的元素
set()
>>> b ^ c # 在b中或者在c中,不是两者共同包含的元素
{'c', 'b', 'd', 'a', 'e'}
复制代码

遍历序列:

>>> for i, v in enumerate(['a', 'b', 'c']):
...     print(f'{i}: {v}')
... 
0: a
1: b
2: c
复制代码

同时遍历两个或者多个序列:

>>> numbers = [1, 2, 3]
>>> strings = ('a', 'b', 'c')
>>> for n, s in zip(numbers, strings):
...     print(f'number: {n}, string: {s}')
... 
number: 1, string: a
number: 2, string: b
number: 3, string: c
复制代码

字典

序列(比如列表和元组)由一系列数字索引,但是字典是通过关键字keys索引。可以把字典想象成一系列键: 值对的集合。{}可以创建一个空字典。

可以使用del删除键值对

执行list(d)作用于一个字典的时候,会按插入顺序返回一个在字典中使用的所有关键字的列表。

使用 in 关键字检查一个键是否在字典中。

>>> a = {'a1': 1, 'a2': 2}
>>> a['a1'] = 5
>>> a
{'a1': 5, 'a2': 2}
>>> del a['a1']
>>> a
{'a2': 2}
>>> list(a)
['a2']
>>> 'a2' in a
True
>>> 'a1' not in a
True
复制代码

遍历字典:

>>> a = {'a1': 1, 'a2': 2, 'a3': 3}
>>> for k, v in a.items():
...     print(f'{k}: {v}')
... 
a1: 1
a2: 2
a3: 3
复制代码

字典相关的一些方法:

方法描述
list(d)返回字典d的所有键的列表
len(d)返回字典d的键值对的数量
reversed(d)返回一个逆序字典键的迭代器。
d.clear()移除字典中的所有项
d.copy()返回字典的浅拷贝
d.get(key[, default])返回字典中键key对应的值,如果没有给出default,默认值是None
d.items()返回字典项的视图((key, value)对)。
d.keys()返回字典项的键的视图。
d.values()返回由字典值组成的视图。
pop(key[, default])如果字典中存在键key,就把键key对应的项移除,并且返回该项的值。否则返回default值。
d.popitem()移除并且从字典中返回 (key, value) 对。
d.setdefault(key[, default])如果字典有键 key ,返回它的值。否则,插入值为default 的键 key ,并返回 defaultdefault默认为 None
d.update([other])使用来自 other 的键/值对更新字典,覆盖原有的键。

流程控制语句

while语句

a = 3
while a >= 0:
    print(a)
    a = a - 1
else:
    print(f'现在a的值是{a}')
复制代码

执行这段代码的结果是:

3
2
1
0
现在a的值是-1
复制代码

如果while语句的条件为真,就会一直执行while 语句里面的表达式。

使用 break 语句会终止循环,并且不会走到else部分,使用 continue 语句会跳过当前循环,回到while a >= 0判断条件是否成立。

else部分是可选的。

if语句

b = 3
if b < 0:
    print('a小于0')
elif b == 0:
    print('a等于0')
else:
    print('a为大于0的值')
复制代码

执行这段代码的结果为:

a为大于0的值
复制代码

可以有一个或者多个elif部分,else部分是可选的。

for 语句

Python中的for语句以序列中出现的顺序遍历任何序列的项。

c = [1, 2, 3]
for item in c:
    print(item)
复制代码

结果:

1
2
3
复制代码

range() 函数在遍历数字索引的时候很好用。

>>> for c in range(1, 3):
...     print(c)
... 
1
2
复制代码

也可以用 break 来终止for循环。 continue 语句会继续循环的下一个迭代。

比较操作

比较操作符innot in检查一个值是否在一个序列中出现。操作符isis not比较两个对象是否一样。

比较操作可能和布尔操作符andor结合使用,比较的结果(或者任何其他布尔表达式的结构)可以被not取反。

布尔操作符andor被称为短路(short-circuit)操作符:它们的参数从左到右被评估,并且评估在输出确定的时候会停止。比如,如果AC是真的,但是B是假的,A and B and C就不会评估表达式C。当作为一个普通值而不是一个布尔值来使用的时候,短路操作符的返回值是最后一个被评估的参数。

注意在表达式中的赋值必须使用海象运算符 :=

序列对象可以被拿来和包含相同序列类型的对象比较。比较使用词典编撰顺序:首先前两个项被比较,如果它们不同,这个比较的结果就出来了;如果它们一样,下两个项会被比较,并且一直这样下去,直到其中的某一个序列结束。

>>> a = [1, 2]
>>> 1 in a
True
>>> 1 not in a
False
>>> a = 2
>>> b = 6
>>> a > 1 and b < 10
True
>>> a == 2 or b < 0
True
>>> c = 5
>>> while c := c - 1:
...     print(c)
... 
4
3
2
1
>>> [1, 2, 3] > [1, 2]
True
复制代码

pass语句

pass语句是一个空的操作,当执行它的时候,什么都不会发生。通常是用来作为占位的。

def f(arg): pass    # 一个暂时没有内容的函数

class C: pass       # 一个暂时没有内容的类
复制代码

函数

1.使用 def定义函数,后面跟着括号以及括号里的形参。

2.函数体的第一个语句是字符串的时候,该语句就是函数的文档字符串(Documentation Strings)。有一些可以根据文档字符串自动生成文档的工具。

3.return 语句返回函数的值。

def e(x):
    '''
    这个函数没什么意义,只是用来演示函数定义方式的
    '''
    print(x)
    return x

e('a')
复制代码

4.函数在执行的时候,所有函数变量赋值都存在局部符号表中。引用变量的时候,会在局部符号表里面查找变量,然后在外层函数局部符号表里面查找变量,在然后是全局符号表,最后是内置名称符号表。

global_var = 1

def outer_func(x):
    '''
    这个函数也只是为了演示,层层嵌套的符号表的,没什么实际意义
    '''
    a = global_var
    b = x

    def inner_func():
        c = b
        return c
    
    c = inner_func()
    d = set([1, 2, 2, 3])
    print(a, b, c, d)


outer_func(2)
复制代码

set函数是内置函数中的一个。

5.在调用函数时会将实际参数(实参)引入到被调用函数的局部符号表中;因此,实参是使用 按值调用来传递的(其中的 始终是对象的 引用 而不是对象的值)。

f1 = {
    'a': 1
}

def f(x):
    x['b'] = 2
    print(x)

f(f1)
print(f1)
复制代码

打印结果是:

{'a': 1, 'b': 2}
{'a': 1, 'b': 2}
复制代码

如果传递的是对象的值,那么第二行打印的f1应该是只有a属性的。

函数参数

有三种形式的参数定义。

1.默认参数

默认参数必须在位置参数之后。

def g(x, y=1):
    print(x + y)

g(2)
复制代码

打印结果是:




    
3
复制代码

默认参数会在定义作用域时的函数定义中被评估。也就是说默认参数取的是函数定义时的那个时间点的值,而不是函数调用时的值,所以下面这个例子打印的是1

i = 1

def g(x=i):
    print(x)

i = 2
g()
复制代码

默认值只会被评估一次。

2.关键字参数

函数可以用 kwarg=value的形式被调用。

def h(x, y=1):
    print(x + y)

h(x=3, y=3)
复制代码

打印的结果为6

3. *arguments**keywords

def k(*arguments, **keywords):
    for argument in arguments:
        print(argument)

    for keyword, value in keywords.items():
        print(f'{keyword}: {value}')

k(*(1, 2), **{'a': 'a_str', 'b': 'b_str'})
复制代码

打印结果:

1
2
a: a_str
b: b_str
复制代码

在函数定义中,def k(*arguments, **keywords)的形参数部分,*arguments是以元组的形式将位置参数收集到arguments变量中,**keywords是以字典的形式将关键字参数收集到keywords变量中。

函数调用部分,*(1, 2)是将元组展开为位置参数,**{'a': 'a_str', 'b': 'b_str'}是将

字典展开为关键字参数。

k(*(1, 2), **{'a': 'a_str', 'b': 'b_str'})函数调用的这句换成以下这句,打印的结果是一样的:

k(1, 2, a='a_str', b='b_str')
复制代码

模块

模块(Modules)是包含 Python 定义和语句的文件。它的文件名是模块名加后缀名 .py 。在模块内部,通过全局变量 __name__ 可以获取模块名。

模块可以导入其他模块。一般把import放到模块的开头,但这不是必须的。

每个模块都有它自己的私有符号表,被作为所有在这个模块中定义的函数全局符号表来使用。因此,模块的作者可以使用模块中的全局变量而不用担心意外地和用户的全局变量的冲突。

新建d.py文件,内容为:

def a():
    print('a')

def b():
    print('b')

def _c():
    print('c')
复制代码

1.在另一个文件中这样引入和使用模块d

import d

d.a()

a = d.a
a()

print(d.__name__)
复制代码

打印结果为:

a
a
d
复制代码

2.直接将模块d中的名字导入另一个模块的符号表中:

from d import a, b

a()
b()
复制代码

3.导入除了以下划线(_)开始的所有的名字。

from d import *

a()
复制代码

通常情况下,不使用这种方法,因为这样可读性较差。

4.设置别名。

设置模块的别名:

import d as d1

d1.a()
复制代码

设置模块中的变量的别名:

from d import a as a1

a1()
复制代码

每个模块只在每个解释器会话中导入一次,如果要重新加载,可以使用importlib.reload()

为了加速模块的加载,Python缓存每个模块被编译的版本到__pycache__目录下,文件名为 module.version.pycversion是对被编译文件的格式进行编码,一般是Python的版本号。

包(Packages)是一个使用“点模块名字”构造Python的模块命名空间的方式。例如,模块名A.B是在一个名为A的包中定义了一个名为B的子模块。

当导入包的时候,Python通过搜索sys.path的目录查找包的子目录。

__init__.py 文件用来让Python将目录下包含的文件作为包来处理。__init__.py可以只是一个空文件,也可以为包执行初始化代码或者设置__all__ 变量的值。如果一个包的 __init__.py 中定义了一个列表名字 __all__,它就会是在from package import * 发生时,被导入的模块名字的列表。

├── b
│   ├── __init__.py
│   └── b1
│       ├── __init__.py
│       ├── b_one.py
│       └── b_two.py
复制代码

因为b文件目录下有__init__.py文件,所以b文件夹以及其中的文件被当作一个包来处理。b1文件夹下,也有__init__.py文件,b1也是一个包,是b的子包。b1文件夹下有两个模块b_one.pyb_two.py,它们的内容分别是:

print('imported_b_one')

def x():
    print('x')
复制代码

和:

print('imported_b_two')

def y():
    print('y')
复制代码

导入模块:

import b.b1.b_one

b.b1.b_one.x()
复制代码
from b.b1 import b_one

b_one.x()
复制代码

导入想要的函数或变量:

from  b.b1.b_one import x

x()
复制代码

当使用 from package import item, 的时候,item可以是一个包的子模块(或者子包),或者是其他定义在包中的名字,比如一个函数、类或者变量。

使用像 import item.subitem.subsubitem这样的语法的时候,除了最后一个item之外的剩下的item都必须是一个包;最后一个item可以是一个模块或者一个包,但是不可以是定义在前一个item中的类、函数或者变量。

类提供了一种把数据和方法绑定在一起的功能。类对象支持两种操作:属性引用和实例化。

class ClassNameA:
    a = 1

    def b(self):
        print(self.a + 1)

print(ClassNameA.a) # 属性引用

instance_a = ClassNameA() # 实例化
instance_a.b()
复制代码

类可以定义一个特殊的 __init__()函数,用于初始化状态。

class ClassNameB:
    def __init__(self, x):
         self.x = x
    
    def a(self):
        print


    
(self.x) # 打印出 123

instance_b = ClassNameB(123)
instance_b.a()
复制代码

继承:

class BaseClassName:
    a = 1

class DerivedClassName(BaseClassName):
    b = 2

instance = DerivedClassName()
print(instance.b) # 打印出 2
复制代码

多重继承:

class A1:
    a1 = 1

class A2:
    a2 = 2

class A3(A1, A2):
    a3 = 3

instance_a3 = A3()
print(instance_a3.a1, instance_a3.a2, instance_a3.a3) # 打印 1 2 3
复制代码

使用 isinstance() 来检查一个实例的类型;使用 issubclass() 来检查类继承。

虚拟环境和包

1.虚拟环境

因为不同项目依赖的包不同,所以需要使用虚拟环境,在一个虚拟环境中对依赖包的操作不会影响到另一个虚拟环境中的依赖包。

pip3 install virtualenv
pip3 install virtualenvwrapper
复制代码

创建虚拟环境:

mkvirtualenv venv_name
复制代码

进入虚拟环境:

workon venv_name
复制代码

退出虚拟环境:

deactivate
复制代码

2.包

使用pip安装、更新以及移除包。

安装最新版本的包:

pip install novas
复制代码

安装特定版本的包:

pip install requests==2.6.0
复制代码

更新包到最新版本:

pip install --upgrade requests
复制代码

从虚拟环境中移除包:

pip uninstall 一个或者多个包名
复制代码

展示特定包的信息:

pip show requests
复制代码

展示安装在虚拟环境中的所有包:

pip list
复制代码

pip freeze会产生一个安装的包的类似的列表。一个通用的惯例是将这个列表放在一个requirements.txt 文件中:

pip freeze > requirements.txt
复制代码

在这之后,可以使用install -r来安装包:

pip install -r
复制代码
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/114870
 
262 次点击