python_笔记_20221103

学习路线&进度记录

学习路线(待整理)

先记录,最后整理

初阶

介绍 | 简明 Python 教程 (gitbooks.io)

进阶

Python Cookbook 3rd Edition Documentation — python3-cookbook 3.0.0 文档

进度记录

  • 20201103

读完《简明教程》,没有总结

  • 20221108

最近在读《python编程快速上手》,没有读完,这本书的好处在于,可能对知识的覆盖不是太全面,但是十分接近于实际应用

2、另一个,廖雪峰的书籍,覆盖比较全面,涉及到边边角角的知识,暂时全力看这一个

基础知识框架整理

一些其它

基本数据类型

整型
浮点型
复数

字符串(单独开一章)

字符串

一些特性
几种表达形式
  • 单引号
  • 双引号
  • 前缀字符r' '----->表示其中的字符不转义
  • 三引号---->解决多行问题以及,以及文档字符串
特殊字符
  • 转义字符```
  • 引号的区分

前缀

  • 自然字符串–>r R
  • unicode字符—>u U
  • byte类型的数据---->b'ABC'

一些操作

格式化输出

字符串和编码 - 廖雪峰的官方网站 (liaoxuefeng.com)

format方法—对字符串进行格式化处理

2.4. 基本语法 | 正文 |《Python 简明教程 2018》| Python 技术论坛 (learnku.com)

##参考例子
整数 = 1

整数 = 100

整数 = -8080

整数 = 0

十六进制写法 = 0xff00

十六进制写法 = 0xa5b4c3d2

分隔号写法 = 10_000_000_000

分隔号写法 = 0x_a1b2_c3d4

浮点数 = 1.23

浮点数 = 3.14

浮点数 = -9.01

科学计数法 = 1.23e9

科学计数法 = 12.3e8

科学计数法 = 1.2e-5

字符串 = 'abc'

字符串 = "xyz"

字符串 = "I'm OK"

转义符号 = 'I\'m \"OK\"!'

转义符号 = 'I\'m learning\nPython.'

转义符号 = '\\\t\\'

强制不转义 = r'\\\t\\'

多行字符串 = '''line1

line2

line3'''

布尔值 = True

布尔值 = False

布尔值 = 3 == 2 + 1

布尔值 = 3 > 2

布尔值 = 3 > 5

布尔值运算 = True and True

布尔值运算 = True or False

布尔值运算 = not False

布尔值运算 = 3 == 2 + 1 and 3 > 2 or not 3 > 5

空值 = None

# 变量

a = 'ABC'

b = a

a = 'XYZ'

# a 是 'XYZ', b 是 'ABC'

# 常量 (全部字母大写)

PI = 3.14159265359

# 运算

10 / 3  # 小数除法: 3.3333333333333335

10 // 3  # 整数除法: 3

10 % 3  # 取余: 1
关于编码知识的总结
utf-8与unicode
  • 在存储与传输中,使用的utf-8
  • 在使用时(装载到内存中进行编辑时)采用的是unicode
字符串的两种视角
  • unicode编码——x='abc' ——可以通过编码encode编码为指定的bytes——len()表示的是字符数
  • byte字节流——X =b'abc'——可以通过decode按照不同的形式进行解码——len()表示的是字节数
具体的使用见

字符串和编码 - 廖雪峰的官方网站 (liaoxuefeng.com)

格式化输出

参考见上

  • 利用%s

  • format()

  • f-string

运算符与表达式

只记一些比较特殊的

数学运算符
  • 乘方——**

  • 除法

    • /非整除
    • //整除
布尔运算符
  • and
  • or
  • not

流程控制

判断
  • if-else
  • elif
    • elif 一旦被执行,就跳过剩下所有语句
    • 所以次序很重要
    • 可以省略else
if name == "Alice":
    print("hi, Alice")
elif age < 12:
    print("you're not Alice, kiddo")

备注

当使用input时,注意input的返回值为字符串类型

##false
birth = input('birth: ')
if birth < 2000:
    print('00前')
else:
    print('00后')
    
    
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() > int() 

##true
s = input('birth: ')
birth = int(s)
if birth < 2000:
    print('00前')
else:
    print('00后')     

循环
  • while
    • 可以有一个else语句
  • for…in 循环
    • 常与range函数搭配
    • range()可以指定步长
    • 同样可以跟一个else语句
# while
number = 23
running = True

while running:
    guess = int(input('Enter an integer : '))

    if guess == number:
        print('Congratulations, you guessed it.')
        # 这会导致 while 循环停止
        running = False
    elif guess < number:
        print('No, it is a little higher than that.')
    else:
        print('No, it is a little lower than that.')
else:
    print('The while loop is over.')
    # 你可以在此处继续进行其它你想做的操作
print('Done')



# for
for i in range(1, 5, 2):
    print(i)
else:
    print('The for loop is over')
  • 备注
    • 在遍历同一个集合时修改该集合的代码可能很难获得正确的结果。通常,更直接的做法是循环遍历该集合的副本或创建新集合
# Strategy:  Iterate over a copy
for user, status in users.copy().items():
    if status == 'inactive':
        del users[user]

# Strategy:  Create a new collection
active_users = {}
for user, status in users.items():
    if status == 'active':
        active_users[user] = status
break与continue
  • 与c语言一致
sys包中的sys.exit()——可以用来提前停止程序

函数

作用域(全局变量&局部变量)与gloal标识符
  • 可以在函数内使用global修饰一个变量,表明此变量为全局变量
x = 50

def func():
    global x

    print('x is', x)
    x = 2
    print('Changed global x to', x)

func()
print('Value of x is', x)

#运行结果
python function_global.py
x is 50
Changed global x to 2
Value of x is 2
空函数
  • pass不能省略,会报错
def nop():
    pass

参数——默认参数值、关键字参数、可变参数
  • 默认参数值

  • 可变参数

    • 单星号——收录到元组中
  • 关键字参数

    • 双星号——收录到字典中
    • 命名关键字参数——限制关键字的名字
      • 函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*
      • 名关键字参数必须传入参数名
      • 可以有缺省值,从而简化调用
  • 参数组合

    • 参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
#默认参数值
def say(message, times=1):
    print(message * times)

say('Hello')
say('World', 5)

$ python function_default.py
Hello
WorldWorldWorldWorldWorld








#可变参数

def total(a=5, *numbers, **phonebook):
    print('a', a)

    # 遍历元组中的所有项
    for single_item in numbers:
        print('single_item', single_item)

    # 遍历字典中的所有项
    for first_part, second_part in phonebook.items():
        print(first_part,second_part)

print(total(10,1,2,3,Jack=1123,John=2231,Inge=1560))

$ python function_varargs.py
a 10
single_item 1
single_item 2
single_item 3
Inge 1560
John 2231
Jack 1123
None


##关键子参数
def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)
    
 >>> person('Michael', 30)
name: Michael age: 30 other: {}   

>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}
            
##命名关键字参数
def person(name, age, *, city, job):
    print(name, age, city, job)
    >>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer
可返回多个值
  • 本质返回单一的值,存放在tuple中
import math

def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny
return与None
  • 当无retuan语句时,返回None
  • print无return语句
spam = print("hello")
print(spam == None)

True


数据结构

参考

序列式

序列数据类型包括列表、字符串、由range()返回的范围对象,以及元组

其共同的一些操作,包括——按索引取值、切片、for循环、len()、in、not in

列表list
底层思想
  • 引用----->浅拷贝
  • list里面的元素的数据类型也可以不同
  • 一些待补充❓
相关操作
  • 索引(可以为负数)
  • 切片
  • len()
  • 连接与复制(+、*)
  • 删除del、pop(i)–默认为末尾
  • in 和 not in
  • 循环
相关方法
  • index(重复时,只操作第一个)
  • append&insert
  • remove(重复时,只操作第一个)
  • pop(i)——>不指定索引,默认为末尾元素
  • sort(按ASCII字符顺序;可指定revesekey关键字)
  • reverse
一些相关函数
  • enumerate()——返回索引与值
  • random.choice()——随机选择
  • random.shuffle()——就地排序(打乱排序)
spam = ['cat', 'bat', 'rat', 'elephant']
#####相关操作
# 索引(可以为负数)
spam[1]
spam[-1]

# 切片
spam[1:4]

#len()
len(spam)

#连接与复制(+、*)
spam = spam + ['A', 'B']
spam = spam *3

#删除del
del spam[2]

# in 和 not in
'cat' in spam
'cat' not in spam

# 循环
for item in spam:
    print(item, end=' ')
##一个
for i in range(len(spam)):
    print('index' + str(i) + 'in spam is :' + spam[i] )
    
    
    
###### 相关方法
#index
spam.index('cat')//1
# append&insert
spam.append('mouse')
spam.insert(1,'chicken')
#remove
spam.remove('cat')
#sort(按ASCII字符顺序,可指定`revese`关键字)
spam.sort()
spam.sort(reverse = True)
spam.sort(key = str.lower)
# reverse
spam.reverse()

###### 一些相关函数

#enumerate()
for index, item in enumerate(spam):
        print('index' + str(i) + 'in spam is :' + spam[i] )

#random.choice()
 random.choice(spam)
    
#random.shuffle()
random.shuffle(spam)



元组tuple(不可变的列表 )
tuple(['cat', 'dog', 5])

list(('cat', 'dog', 5))
字典dictionary(键值对)
相关操作
  • 索引

  • 添加

  • in&not in——相应的键key是否存在

方法
  • key()——注意返回的不是列表,不可改变

  • values()——注意返回的不是列表,不可改变

  • items()——注意返回的不是列表,不可改变

  • get()——检查是否存在相应的键key,若不存在可以指定返回的备用值

  • setdefault()——为某一个键设置一个默认值

  • pop(key)——删除

技巧
  • 避免key不存在
    • in&not in——相应的键key是否存在
    • get()——检查是否存在相应的键key,若不存在可以指定返回的备用值
spam = {'name': 'zophie', 'age': 7}

###### 相关操作
# 索引
spam['name']

# 添加
spam['sex'] = 'man'
# `in`&`not in`
if 'name' in spam: 
    print(spam['name'])
   

###### 方法
# keys()
for k in spam.keys():
    print(v)

# values()
for v in spam.values():
    print(v)
    
# items()
for k,v in spam.items():
    print(v)
    
# get()
spam.get('set', 0)

# setdefault()
spam.setdefault('sex', 'man')

非序列式
集合set
  • 定义时,要提供一个list作为输入集合
  • key不重复
相关操作
  • in&not in
方法
  • copy()
  • add()
  • issuperset()
  • remove
  • 求并集&
>>> bri = set(['brazil', 'russia', 'india'])
>>> 'india' in bri
True
>>> 'usa' in bri
False
>>> bric = bri.copy()
>>> bric.add('china')
>>> bric.issuperset(bri)
True
>>> bri.remove('russia')
>>> bri & bric # 或者是 bri.intersection(bric)
{'brazil', 'india'}



一些易混淆
# 定义的区分
## list
shoplist = ['apple', 'mango', 'carrot', 'banana']

##元组(圆括号可选)
zoo = ('python', 'elephant', 'penguin')
###空元组
myempty = ()
###单元组(必须在且仅在第一个项的后面用一个逗号来指定该元组)
singleton = (2 , )


##字典
ab = {
    'Swaroop': 'swaroop@swaroopch.com',
    'Larry': 'larry@wall.org',
    'Matsumoto': 'matz@ruby-lang.org',
    'Spammer': 'spammer@hotmail.com'
}

## 集合(要创建一个set,需要提供一个list作为输入集合)
 s = set([1, 2, 3])

高级特性

  • 切片
  • 迭代
  • 列表生成式
  • 生成器
  • 迭代器

用到时,再查迭代器 - 廖雪峰的官方网站 (liaoxuefeng.com)

关于iterable类型与iteerator类型

凡是可作用于for循环的对象都是Iterable类型;

凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

集合数据类型如listdictstr等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

列表生成式

用于简化列表的生成,并可对列表中的元素进行操作,以及使用if语句进行判断


>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]


# 使用两层循环,可以生成全排列
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

#使用两个变量来生成list
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']
生成器

参考

[(219条消息) python(列表生成式/器)_huo_1214的博客-CSDN博客](https://blog.csdn.net/huo_1214/article/details/79209893#:~:text=python (列表生成式%2F器) 1 %23列表生成式是快速生成一个列表的一些公式 2 numbers %3D [],in range ( 0%2C 101 )] More items)

  • 不必创建完整的列表,一边循环一边计算
  • 两种定义方法
    • 把一个列表生成式的[]改成()
    • 如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator函数,调用一个generator函数将返回一个generator:
  • generator 函数的使用
    • 首先要生成一个generator对象,然后用next()函数不断获得下一个返回值
    • 函数改成generator函数后,我们基本上从来不会用next()来获取下一个返回值,而是直接使用for循环来迭代:
    • 调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator
  • generator 函数的执行流程
    • 在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
#创建
#1
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
#2
def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1
    return 'done'
>>> f = fib(6)
>>> f
<generator object fib at 0x104feaaa0>

#打印方式一
>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> next(g)
25
>>> next(g)
36
>>> next(g)
49
>>> next(g)
64
>>> next(g)
81
>>> next(g)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
打印方式二
>>> g = (x * x for x in range(10))
>>> for n in g:
...     print(n)

异步IO

模块与包

参考6. 模块 — Python 3.11.0 文档

模块与包的理解
  • 一个包含很多方法和变量并以 .py 为扩展的文件。(每一个pyhon文件就是一个模块)

  • 聚合——可以将不同模块聚合为包,也可以将不同包聚合为一个更高层的包,在文件中包表示为含有——init.py文件的目录,该文件可以执行包的初始化代码,或设置_all_变量(列表——可用于显性指示导入哪些子模块,当从包中导入``*`时)

  • 包是一种用“点式模块名”构造 Python 模块命名空间的方法。例如,模块名 A.B 表示包 A 中名为 B 的子模块。正如模块可以区分不同模块之间的全局变量名称一样,点式模块名可以区分 NumPy 或 Pillow 等不同多模块包之间的模块名称。

字节码文件
  • python运行原理(解释性)——解释器会将源程序转换成一种被称为字节码.pyc的中间形式,然后将字节码转换成你的计算机的机器语言,然后运行它
  • 了快速加载模块,Python 把模块的编译版缓存在 __pycache__ 目录中,文件名为 module.*version*.pyc
模块的检索与sys.path
  • 首先搜索具有该名称的内置模块,模块的名字被列在 sys.builtin_module_names
  • 然后在变量 sys.path 给出的目录列表中搜索
    • sys.path从以下位置初始化
      • 输入脚本的目录(或未指定文件时的当前目录)。
      • PYTHONPATH (目录列表,与 shell 变量 PATH 的语法一样)。
      • 依赖于安装的默认值(按照惯例包括一个 site-packages 目录,由 site 模块处理)。
导入格式
  • 模块
import [模块名]

#导入所有不以下划线(_)开头的名称,一般不用
from [模块名] import * 

from [模块名] import [具体的变量或是函数名]

from [模块名] as [别名] 

from [模块名] import [具体的变量或是函数名] as [别名] 

    • 基本同上,但有一些地方比较模糊,暂时够用
  • 以脚本形式执行脚本
关于模块的定义与_name_
  • 每一个python模块都定义了各自的_name_,可以通过这个让模块在被导入和独立运行时执行不同的操作

  • 举例

#!/usr/bin/env python3#第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行
# -*- coding: utf-8 -*-#第2行注释表示.py文件本身使用标准UTF-8编码;

' a test module '

__author__ = 'Michael Liao'

import sys

def test():
    args = sys.argv
    if len(args)==1:
        print('Hello, world!')
    elif len(args)==2:
        print('Hello, %s!' % args[1])
    else:
        print('Too many arguments!')
        
        
##此if语句当一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。
if __name__=='__main__':
    test()

关于作用域问题

使用模块 - 廖雪峰的官方网站 (liaoxuefeng.com)

后面再补充

  • 类似__xxx__这样的变量是特殊变量,可以被直接引用,但是有特殊用途,比如上面的__author____name__就是特殊变量,hello模块定义的文档注释也可以用特殊变量__doc__访问,我们自己的变量一般不要用这种变量名;
  • 类似_xxx__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc__abc等;

输入与输出

错误和异常

函数式编程

面向对象

核心思想

IO编程

异步IO与同步IO

异步复杂性高

  • 回调模式
  • 轮询模式

文件IO

文件路径问题

文件路径
参考

[(219条消息) Python I/O(读写)详解 文件路径][绝对路径][相对路径][打开指定文件][读写文件][关闭指定文件]_码农阿杰的博客-CSDN博客_python 读取文件的绝对路径

(219条消息) 关于python文件读写的路径问题_永不落后于人的博客-CSDN博客_python要读取的文件放在哪里

windows下的路径
  • window下以\为分隔符

  • 当用字符串表示相关路径时,又涉及到转义字符问题,如c:\\bacon

  • 在用pathlib包中的一些函数,返回的window下的路径可能表示为/,只是类似于linux

pathlib与os
功能pathlibos
Parh(’spam‘,’bacon’, ‘eggs’)///Path(‘spam’) /‘bacon’ / ‘eggs’
Path.cwd()//Path.home()
Path(r’“c:\users\A1\spam”).mkdir
path = Path(r’“c:\users\A1\spam”); path.is_absolute
os及os.path模块

思想

  • 对于路径当作字符串进行处理
  • 由于os的区别,便于移植,拼接分割,采用特定的函数进行处理
  • 相对路径与绝对路径,不太清楚如何处理的,不过可以采用相对路径的方式

# 查看
os.path.abspath('.')#当前路径,一些补充见下文
#路径的拼接与拆解

>>> os.path.join('/Users/michael', 'testdir')
'/Users/michael/testdir'

>>> os.path.split('/Users/michael/testdir/file.txt')
('/Users/michael/testdir', 'file.txt')

>>> os.path.splitext('/path/to/file.txt')
('/path/to/file', '.txt')


#目录的创建与删除
# 然后创建一个目录:
>>> os.mkdir('/Users/michael/testdir')
# 删掉一个目录:
>>> os.rmdir('/Users/michael/testdir')


文件的重命名与删除
# 对文件重命名:
>>> os.rename('test.txt', 'test.py')
# 删掉文件:
>>> os.remove('test.py')

#拷贝见shutil模块

参考

os.getcwd && os.path.abspath详解https://blog.csdn.net/funnypython/article/details/787

文件读写
标准流程
#读文件
#打开
file = open(file_name, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
#读取
file.read()## 一次读取全部内容
file.read(size) # 每次最多读取size个字节的内容
file.readline() # 每次读取一行内容
file.readlines() #一次读取所有内容并按行返回list,一般用于读取配置文件
for line in file.readlines():
    print(line.strip()) # 把末尾的'\n'删掉
#关闭
file.close()

#异常处理版本
try:
    f = open('/path/to/file', 'r')
    print(f.read())
finally:
    if f:
        f.close()
        
        
#with语句,自动调用close方法
with open('/path/to/file', 'r') as f:
    print(f.read())
        
          
            
#写文件
f = open('/Users/michael/test.txt', 'w')
f.write('Hello, world!')
f.close()

文件读写格式等见链接
  • [(219条消息) python-文件方法(读写)_不侠居的博客-CSDN博客_python 读写文件](https://blog.csdn.net/m0_46778548/article/details/121201868#:~:text=python-文件方法(读写) 1 1.文件对象 在python中用 open () 可以创建一个文件对象。 open,3.1读 有三个方法可以使用 file.read ( [size]) 从文件读取指定的字节数,如果未给定或为负则读取所有。 例1: )

内存空间IO

stringIO
#写入

#导入
from io import StringIO
f = StringIO()
f.write('hello')
print(f.getvalue())

#读取
from io import StringIO
f = StringIO('Hello!\nHi!\nGoodbye!')
while True:
    s = f.readline()
    if s == '':
	break
	 print(s.strip())

Hello!
Hi!
Goodbye!
BytesIO

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-U2d8iRpU-1675080472174)(./python_%E7%AC%94%E8%AE%B0_20221103.assets/image-20230127151750145.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KpFzlEkb-1675080472175)(./python_%E7%AC%94%E8%AE%B0_20221103.assets/image-20230127151758944.png)]

异步IO

  • 同步IO必须等待IO
  • 当遇到IO操作时,代码只负责发出IO请求,不等待IO结果,然后直接结束本轮消息处理,进入下一轮消息处理过程。当IO操作完成后,将收到一条“IO完成”的消息,处理该消息时就可以直接获取IO操作结果。

参考

Python 高级编程之协程和异步 IO - CodeAntenna

有些复杂,建议后面搭配python-cookbook的书看一下

简单总结几种IO方式

总体来说,分为同步IO和异步IO,两者的区别在于——进程是否等待IO操作完成

同步IO又分为阻塞式与非阻塞式,区别在于调用函数时,当前线程是否被挂起,在阻塞式中,最基础的是轮询的方式,使用while循环,在这基础之上,又发展出IO复用的方式,具体有select ,poll,epoll等,核心在于一个线程监听,当监听到时,交给其它线程进行处理

有点不太对,几种方式可以看作是递进的方式

协程

网络编程

TCP编程

客户端

import socket

s = socket.socket(socket.AF_INET, socket.SOCk_STREAM)
s.connect(('www.sina.com.cn', 80))
s.send(b'GET / HTTP/1.1\r\nHost:www.sina.cn\r\nConnection: close\r\n\r\n')

buffer = []
while True:
    d = s.recv(1024)
    if d:
        buffer.append(d)
    else:
        break
data = b''.join(buffer)
s.close()

header, html = data.split(b'\r\n\r\n', 1)
print(header.decode('utf-8'))

with open('sina.html', 'wb') as f:
    f.write(html)

服务端

s = socket.socket(socket.AF_INET, socket.SOCK_Stream)
s.bind(('127.0.0.1', 9999))
s.listen(5)
print('Waiting for connection...')
while True:
    sock, addr = s.accept()
    t = threading.Thread(target = tcplink, args = (sock, addr))
    t.start()
    
    
    
def tcplink(sock. addr):
    print('Accept new connection from %s : %S...' %addr)
    sock.send(b'Welcome')
    while True:
        data = sock.recv(1024)
        time.sleep(1)
        if not dada or data.decode ('utf-8') == "exit":
            break
         sock.send('Hello, %s!' %data.decode('utf-8').encode('utf-8'))
    sock.close()
    print("Conection from %s:%s closed" %addr)
    

测试


s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 建立连接:
s.connect(('127.0.0.1', 9999))
# 接收欢迎消息:
print(s.recv(1024).decode('utf-8'))
for data in [b'Michael', b'Tracy', b'Sarah']:
    # 发送数据:
    s.send(data)
    print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()
UDP编程

服务器

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind('127.0.0.1', 9999)
print('Bind UDP on 9999...')
while True:
    data, addr = s.recvfrom(1024)
    print('recvived from %s :%s.' %addr)
    s.sendto(b'Hello, %s!' %data, addr)

客户端

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Michael', b'Tracy', b'Sarah']:
    s.sendto(data, ('127.0.0.1', 9999))
	print (s.recv(1024).decode('utf-8'))
    
s.close()

随记

关于sys.path与sys.argv
  • sys.argv——保存有命令行参数的字符串 列表

    • sys.argv[0]`中存放着当前运行的模块名
  • sys.path 是模块导入时要搜索的目录列表。

    • sys.path 的第一个字符串是空的,表示当前目录也是 sys.path 的一部分,与 PYTHONPATH 环境变量是相同的
关于python3 range()
  • Python3 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表
  • Python3.x 中 range() 函数返回的结果是一个整数序列的对象,而不是列表。
  • Python3 list() 函数是对象迭代器,可以把range()返回的可迭代对象转为一个列表,返回的变量类型为列表。

Python3 range() 函数用法 | 菜鸟教程 (runoob.com)

lambda函数
  • 小的匿名函数

Python Lambda (w3school.com.cn)

python网络编程
  • 在套接字中,使用的是元组

交互模式输入多行代码

(219条消息) Python交互模式如何进行多行输入(3.8.1版本)_坤舆小菜鸡的博客-CSDN博客
4).decode(‘utf-8’))
s.send(b’exit’)
s.close()




#### UDP编程

服务器

~~~python
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind('127.0.0.1', 9999)
print('Bind UDP on 9999...')
while True:
    data, addr = s.recvfrom(1024)
    print('recvived from %s :%s.' %addr)
    s.sendto(b'Hello, %s!' %data, addr)

客户端

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Michael', b'Tracy', b'Sarah']:
    s.sendto(data, ('127.0.0.1', 9999))
	print (s.recv(1024).decode('utf-8'))
    
s.close()

随记

关于sys.path与sys.argv
  • sys.argv——保存有命令行参数的字符串 列表

    • sys.argv[0]`中存放着当前运行的模块名
  • sys.path 是模块导入时要搜索的目录列表。

    • sys.path 的第一个字符串是空的,表示当前目录也是 sys.path 的一部分,与 PYTHONPATH 环境变量是相同的
关于python3 range()
  • Python3 range() 函数返回的是一个可迭代对象(类型是对象),而不是列表类型, 所以打印的时候不会打印列表
  • Python3.x 中 range() 函数返回的结果是一个整数序列的对象,而不是列表。
  • Python3 list() 函数是对象迭代器,可以把range()返回的可迭代对象转为一个列表,返回的变量类型为列表。

Python3 range() 函数用法 | 菜鸟教程 (runoob.com)

lambda函数
  • 小的匿名函数

Python Lambda (w3school.com.cn)

python网络编程
  • 在套接字中,使用的是元组

交互模式输入多行代码

(219条消息) Python交互模式如何进行多行输入(3.8.1版本)_坤舆小菜鸡的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值