NLP自然语言处理:自然语言处理(NLP)就是在机器语言和人类语言之间沟通的桥梁,以实现人机交流的目的。人类通过语言来交流,狗通过汪汪叫来交流。机器也有自己的交流方式,那就是数字信息。
BERT预训练模型:
Word2vec:
#-*- coding: utf-8 -*
在文件读写中只有open的文件需要close,其他的是直接在文件中读取
打开文件的方式:
open函数:f=open(path,mode,buffering,encoding,errors)在c里面表示一个指针,指向一个文件流, path表示文件路径,mode表示文件读写方式(r/rb只读,文件指针指向文件的开头;r+文件指针在文件的开头;w只写,会覆盖,指针指在文件开头;w+先写再读,先覆盖;a指针指在文件末尾);buffering表示设置缓冲策略0关闭缓冲,1行缓冲,>1固定大小的块缓冲(缓冲提高执行效率,减少内存负担,读取文件时,数据先进入缓冲区而不是直接写入磁盘区;如参数为1,写入文件时,写一行,同步一行);encoding表示解码方式;error表示处理编码错误的方式(strict;ignore忽略错误;replace将错误部分替换为?;backslashrepalce用 Python 的反斜杠转义序列替换格式错误的数据。)
file=f.read()按字符读入,生成一个字符串str,我们可以对字符串做一个处理,从而将其按行生成列表即使用split()按照空白符分解
file=f.readlines()按行读取,且生成一个列表,带有\n,因此使用strip()去除字符串列表每个元素首尾的空白字符,lis=[i.strip() for i in file]
file=f.readlin()只读取一行字符串,会读取\n字符
f=open("new_s.txt","r",encoding="utf-8")
lis=""
while TRUE:
s=f.read()
if s!='':
lis+=s
else:
break
lis=lis.split("\n")
print(type(lis))
print(lis)
文件写入的方式:
[(9条消息) [python]—list列表写入txt文档的多种方法_阿斯顿菊花奶茶的博客-CSDN博客_python列表写入txt](https://blog.csdn.net/weixin_45699912/article/details/117328629#:~:text=[python]—list列表写入txt文档的多种方法 1 1.writelines ()直接写入 2 2.str转化为字符串再写入,3 3.for循环写入 4 4.使用.join函数修改列表 5 5.读取数据)
csdn:Python读取csv文件的几种方法_domoNaruto的博客-CSDN博客_python 读取csv
import csv
from email import header
f=open(".csv","r",encoding="utf-8")
file=csv.reader(f)
for row in file:
print(row)
##输出指定行
list(file)
file的格式为_csv.reader貌似无法输出指定行
按行写入csv文件
import csv
#python2可以用file替代open
with open("test.csv","w") as csvfile: ##最重要
writer = csv.writer(csvfile)
#先写入columns_name
writer.writerow(["index","a_name","b_name"])
#写入多行用writerows
writer.writerows([[0,1,3],[1,2,3],[2,3,4]])
import numpy as np
data = np.loadtxt(open("路径.csv","rb"),delimiter=",",skiprows=n,usecols=[2,3])
import pandas as pd
f=pd.read_csv("D:\\经管大三\\现代程序设计\\week4\\twitch_gamers\\large_twitch_features.csv","r",encoding="utf-8")
print(type(f))##输出格式为数据框
f-print可以快速打印,且简洁。
a=1.23142536
b=3.124156657
#方式一
print("a{:.2f}daaf{:.4f}agfqfag".format(a,b))
#方式二
print(f"a{a:.2f}daaf{b:.4f}agfqfag")
#两者的输出结果相等
(8条消息) python中的print信息写入文件_hr_net的博客-CSDN博客_python将print结果写入文件
python中只有模块、类、函数(def、lambda)才会引入新的作用域。其他的代码块如循环语句,条件语句等并不会引入新的作用域。
(11条消息) 【Python】Python中令人头疼的变量作用域问题,终于弄清楚了_风度78的博客-CSDN博客
可变参数传入函数:(其实传入一个实参)
Python函数参数传递机制(超级详细) (biancheng.net)
其实对于可变类型(列表、字典、集合传入的时候类似于一个指针,传入的是一个指向参数存储位置的地址,因此对于地址进行操作,指向发生改变)
然而对于不可变类型(整型、元组、字符串传入时,会将数据传入一个内存副本中,函数对副本进行修改,而不对原数据产生影响)
python如何使用全局变量-大盘站 - 大盘站 (dapan.cc)
[(8条消息) python判断变量是否为数字、字符串、列表、字典等_Fybon的博客-CSDN博客_判断列表元素是否为数字](https://blog.csdn.net/Fybon/article/details/102931750?ops_request_misc=%7B%22request%5Fid%22%3A%22166652787416782395319561%22%2C%22scm%22%3A%2220140713.130102334…%22%7D&request_id=166652787416782395319561&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-102931750-null-null.142v59pc_rank_34_queryrelevant25,201v3control_2&utm_term=python 判断元素是否为数字&spm=1018.2226.3001.4187)
a = 1
b = [1,2,3,4]
c = (1,2,3,4)
d = {‘a‘:1,‘b‘:2,‘c‘:3}
e = "abc"
if isinstance(a,int):
print "a is int"
else:
print "a is not int"
if isinstance(b,list):
print "b is list"
else:
print "b is not list"
if isinstance(c,tuple):
print "c is tuple"
else:
print "c is not tuple"
if isinstance(d,dict):
print "d is dict"
else:
print "d is not dict"
if isinstance(e,str):
print "d is str"
else:
print "d is not str"
string_date='2016-8-1'
year,month,day=map(int,string_date.split('-'))
s=Data_test(year,month,day)
(5条消息) 【Python】pandas计算DataFrame各列相关系数以及显著性检验_Asher117的博客-CSDN博客_pandas显著性检验
(4条消息) python对象赋值操作中的空间地址变化_YuanOo。的博客-CSDN博客
Python 直接赋值、浅拷贝和深度拷贝解析 | 菜鸟教程 (runoob.com)
import copy
l1=list(range(0,10))
l1_c=l1
l1_b=l1[:]
print(id(l1))#2787012655424
print(id(l1_c))#2787012655424
print(id(l1_b))#2787012654912
#对于赋值的情况,重新开辟了一个内存,因此id改变了,当直接copy或者赋值时,指向同一内存,id相同
l1_c=l1.copy()
l1_c=copy.copy(l1)
l1_c=copy.deepcopy(l1)
l1_c[0],l1_c[-1]=-1,-9
print(l1)
print(l1_c)
l2=list(list(range(0,i)) for i in range(1,5))
#l2_c=l2[:]
#l2_c=l2.copy()
#l2_c=copy.copy(l2)
#l2_c=copy.deepcopy(l2)
#l2_c[0][0],l2_c[-1][-1]=-1,-3
#print(l2)
#print(l2_c)
csdn:python 序列化_python怎么序列化_黄明轩的博客-CSDN博客
C语言中文网:[Python pickle模块:实现Python对象的持久化存储 (biancheng.net)](http://c.biancheng.net/view/5736.html#:~:text=pickle.load ()函数 此函数和 dump,() 函数相对应,用于将二进制对象文件转换成 Python 对象。)
Python 异常处理 | 菜鸟教程 (runoob.com)
def main():
try:
a = input("输入一个数:")
if(not a.isdigit()):
raise ValueError("a 必须是数字")
return a
except ValueError as e:
print("引发异常:",repr(e))
a=main()
print(a)
当出现raise时,会直接出发except报错,从而跳过return,并不会返回return值
try:
dddd
except <error1>:
ddddd
except <error2>:
dddd
Python:用户自定义异常 - xiaobai小白 - 博客园 (cnblogs.com)
class AccoutError(Exception):
def __init__(self,user):
self.user=user
class AccountNegativeDepositError(AccoutError):
def __init__(self,user,m):
self.user=user
self.m=m
self.message="{} deposit negative amount: {}".format(user,m)
class AccountBalanceNotEnoughError(AccoutError):
def __init__(self,user,balance, m):
self.user=user
self.m=m
self.balance=balance
self.message="{}'s balance {} is smaller than the withdraw amount of {}. Loan is suggested.".format(user,balance,m)
class Account:
def __init__(self,user,balance):
self._user=user
self._balance=balance
def set_balance(self,balance):
self._balance=balance
def get_balance(self):
return self._balance
def get_user(self):
return self._user
def deposit(self,m):
if m<0:
raise AccountNegativeDepositError(self.get_user(),m)
else:
self.set_balance(self.get_balance()+m)
def withdraw(self,m):
if self.get_balance()<m:
raise AccountBalanceNotEnoughError(self.get_user(),self.get_balance(),m)
else:
self.set_balance(self.get_balance()-m)
account=Account('zjc',100)
try:
#account.deposit(-100)
account.withdraw(10000)
except AccountNegativeDepositError as ande:
print(ande.message)
except AccountBalanceNotEnoughError as abnee:
print(abnee.message)
except AccoutError:
print('noname exception')
else:
print('no except...')
print(account.get_balance())
通过finally子句实现,定义无论在任何情况下都会执行的清理行为。无论try子句有无发生异常,finally子句都会执行,即使try执行了return
python的try finally (还真不简单) - 永远的幻想 - 博客园 (cnblogs.com)
with open as调用结束自动清理空间
(8条消息) python try: except: continue 语句,避免程序崩溃_胖虎是只mao的博客-CSDN博客
【进阶Python】第八讲:代理模式 - 知乎 (zhihu.com)
在不修改原始代码的前提下增强或扩展既有的功能
Python 函数装饰器 | 菜鸟教程 (runoob.com)
Python @函数装饰器及用法(超级详细) (biancheng.net)
装饰器如何保存函数名称不发生变化?
def g(装饰器参数):
def deractor(func):
@functools.wraps(func) #为了保持now()的名字不变
def wrapper(*args,**kwrgs):
return func(*,**)
return wrapper
return deractor
@g
def now():
pass
now()#相当于g(装饰器参数)(now)()
(11条消息) Python的functools模块_Python之简的博客-CSDN博客_functools
(11条消息) Python 标准库 functools 模块详解_擒贼先擒王的博客-CSDN博客_functools
functools.partial(fun,a)
固定部分参数,返回新函数
import functools
def add(a, b):
return a + b
add3 = functools.partial(add, 3)
add5 = functools.partial(add, 5)
print(add3(4))
print(add5(10))
'''
7
15
'''
functools.reduce(function, iterable, initializer=None)
将一个序列归纳为输出,Initializer为从什么值开始.iterable指的是可迭代对象
def f(x,y):
return x*10+y
print(reduce(f,[1,2,3,4]))
#类似与累计拆分
1*10+2=12
12*10+3=123
123*10+4=1234
#下列从2的值开始做序列归纳,结果为21234
def f(x,y):
return x*10+y
print(reduce(f,[1,2,3,4],2))
将类中的函数变成属性直接调用,可以获取私有属性
(11条消息) Python @property装饰器详解_NickTheRock的博客-CSDN博客_python property装饰器
Python_getter和setter方法 - 知乎 (zhihu.com)
class Rect:
def __init__(self,area):
self.__area = area
@property
def area(self):
return self.__area
rect = Rect(30)
#直接通过方法名来访问 area 方法
print("矩形的面积是:",rect.area)
@方法名.setter
修改属性值 ,实现属性的读写
@area.setter
@方法名.setter
def 方法名(self, value):
代码块
class Student(object):
@property
def score(self):
return self.__score
@score.setter
def score(self,value):
if not isinstance(value,int):
raise ValueErro('score must be an integer')
if value < 0 or value > 100:
raise ValueError('score must between 0~100')
self.__score=score
##调用函数和改变属性时直接将实例函数类似于实例属性调用的形式
s=Student()
s.score=60
s.score
s.score=9999
@方法名.deleter
删除属性
@area.deleter
python @classmethod 的使用场合 - 知乎 (zhihu.com)
Python进阶-----静态方法(@staticmethod) - Meanwey - 博客园 (cnblogs.com)
使得在使用修饰器时返回的仍然是调用的函数名,而不是内嵌函数
(11条消息) Python装饰器中@wraps作用_Shaun_X的博客-CSDN博客_@wraps python
def wrapper(func): # func = holiday
def inner(*args, **kwargs):
print('在被装饰的函数执行之前做的事')
ret = func(*args, **kwargs)
print('在被装饰的函数执行之后做的事')
return ret
return inner
@wrapper #holiday = wrapper(holiday)
def holiday(day):
''' 这是一个放假通知 '''
print('全体放假%s天'%day)
return '好开心'
print(holiday.__name__)print(holiday.__doc__)该实例运行结果为: inner 我是inner函数的注释
上述例子中:holiday()函数为被装饰的函数,其实际内存地址指向了inner()装饰函数。也就是说如果我们想打印holiday()函数的名字、注释等,实际打印的是inner()函数的函数名、注释
那么怎么打印holiday()函数的名字跟注释等方法呢?
################
from functools import wraps
def wrapper(func): # func = holiday
@wraps(func)
def inner(*args, **kwargs):##通用格式,便于func传参
print('在被装饰的函数执行之前做的事')
ret = func(*args, **kwargs)
print('在被装饰的函数执行之后做的事')
return ret
return inner
@wrapper # holiday = wrapper(holiday)
def holiday(day):
''' 这是一个放假通知 '''
print('全体放假%s天'%day)
return '好开心'
print(holiday.__name__)
print(holiday.__doc__)
该实例运行结果为: holiday 这是一个放假通知
我们引入了内置functools模块中的装饰器wraps,这时候就可以正常打印被装饰函数的名字、注释等方法了。
通用格式 用于修饰名字,注意传入函数参数,所以外面还有一个函数def dec(fun):…return wrapper
@wraps(func)
def wrapper(*args,**kwargs):
print(text+' '+'call '+func.__name__)
return func(*args,**kwargs)
return wrapper
Python性能分析工具Profile - -零 - 博客园 (cnblogs.com)
通过memory_profiler库
from memory_profiler import profile
@profile
def my_func():
a = [1] * (10 ** 6)
b = [2] * (2 * 10 ** 7)
del b
return a
my_func()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EFY3XQLy-1678455709917)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20221023161118520.png)]
(8条消息) Python性能分析工具Line_profiler_乔宇同学的博客-CSDN博客
import time
@profile
def test_time():
for i in range(100):
a=[1]*(10**4)
b=[2]*(10**4)
pass
test_time()
上面的代码需要通过命令行运行
kernprof -lv ld.py##ld.py为文件名
下面的代码在程序中执行
from line_profiler import LineProfiler
import random
def do_other_stuff(numbers):
s = sum(numbers)
def do_stuff(numbers):
do_other_stuff(numbers)
l = [numbers[i]/43 for i in range(len(numbers))]
m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
numbers = [random.randint(1,100) for i in range(1000)]
lp = LineProfiler()#调用类方法
lp.add_function(do_other_stuff) # add additional function to profile
lp_wrapper = lp(do_stuff)
lp_wrapper(numbers)#对打包好的函数进行测试
lp.print_stats()#打印状态结果
返回函数不宜引用任何循环变量,或者后续会发生变化的变量
python中闭包详解 - 知乎 (zhihu.com)
(8条消息) tqdm-python实现进度条_Dream seeker_z的博客-CSDN博客_tqdm 进度条长度
from tqdm import tqdm
import time
import pandas as pd
import numpy as np
alist = list('letters')
bar = tqdm(alist)
for letter in bar:
bar.set_description("Now get "+str(letter))
time.sleep(1)
df = pd.DataFrame(np.random.randint(0, 100, (10000000, 60)))
#print(df.shape)
tqdm.pandas(desc="Processing...")
df.progress_apply(lambda x: x**2)
也被称作发布(publish)-订阅(subscribe)模式
一个目标对象管理所有依赖于它的观察者对象,并且在它本身的状态改变时主动发出通知;观察者模式完美地将观察者和被观察的对象分离
Python设计模式:观察者模式 - 知乎 (zhihu.com)
python设计模式之观察者模式 - sfencs - 博客园 (cnblogs.com)
这种方法有点像挂起,延迟使用,关键在于setter函数,当发现属性价格变动且达到提醒的范围时,调用notify函数,此时notify函数里需要写提醒所有观察者的函数
@price.setter
def price(self,value):
if self._price>value:
self.notify()
self._price=value
import time
class Investor:##接口,负责提醒观察者
def __init__(self,name,stock):#传入为一个观察者的名称和一个股票实例
self._name=name
self._stock=stock
@property
def stock(self):
return self._stock
@stock.setter
def stock(self,value):
self._stock=value
def update(self):
print("{} invest on {} with price {}: sell it now!!!".format(self._name,self._stock.name,self._stock.price))
class Stock:#subject用于存储观察者信息以及观察的类
def __init__(self,name,price):
self._name=name
self._price=price
self._investors=[]
@property
def name(self):
return self._name
@property
def price(self):
return self._price
@price.setter
def price(self,value):
if self._price>value:
self.notify()
self._price=value
def attach(self,investor):
self._investors.append(investor)
#deattach
def notify(self):
for investor in self._investors:
investor.update()#update作为操作函数,对所有的观察者通风报信
def main():
s=Stock('区块链',11.11)
i1=Investor('zjc',s)
i2=Investor('lys',s)
s.attach(i1)
s.attach(i2)
s.price=13
time.sleep(1)
s.price=10
if __name__=='__main__':main()
(6条消息) Python @abstractmethod 抽象方法_jiang_huixin的博客-CSDN博客_python abstractmethod
Python 抽象类 (zditect.com)
Python生成器详解 (biancheng.net)
yield类似于return,会在yield处中断运行,利用next可以继续执行yield后的代码,直到碰到下一个yield
第一次调用函数的时候返回的是一个生成器,当调用next的时候,则返回yield后的数值
def fib(max):
n,a,b=0,0,1
while(n<max):
yield b
a,b=b,a+b
n+=1
return 'done'
print(fib(6))
f=fib(6)
while True:
try:
print(next(f))
except StopIteration as si:
print(si.value)
break
###从上面两个代码的返回结果可以明显看出不同,第一个print直接返回一个生成器的,第二个f也为一个生成器,但是next(f)则返回了yield后的数值
StopIteration还可以用于规定完成表示迭代完成,防止无限循环
#!/usr/bin/python
# -*- coding: UTF-8 -*-
# 首先获得Iterator对象:
it = iter([1, 2, 3, 4, 5])
# 循环:
while True:
try:
# 获得下一个值:
x = next(it)
print(x)
except StopIteration:
# 遇到StopIteration就退出循环
break
def fib(max):
n,a,b=0,0,1
while(n<max):
yield b
a,b=b,a+b
n+=1
return 'done'
print(fib(6))
#print(len(fib(6)))
for f in fib(6):
print(f)
f=fib(6)
while True:#使用这一步的最后打印的是done
try:
print(next(f))
except StopIteration as si:
print(si.value)
break
Python next() 函数 | 菜鸟教程 (runoob.com)
可以被next()函数调用并不断返回下一个值的对象称为迭代器
##判断一个对象是否可以被迭代
from collections import Iterable
isinstance([1,2,3],Iterable)
把一个类作为一个迭代器使用需要在类中实现两个方法 __ iter __ () 与 __ next __()
__ iter __ ()返回一个特殊的迭代器对象,这个迭代器对象实现了 __ next __()方法
__ next __ () 方法返回下一个元素并通过StopIteration 异常标识迭代完成
什么是抽象类? - 知乎 (zhihu.com)
抽象类不能做实例化
抽象类有啥用?
(11条消息) python抽象类有必要吗_Python为什么要用抽象类(abc模块)?_weixin_39837207的博客-CSDN博客
Type()函数,不仅仅用于返回对象的类型,还可以用于创建类对象,函数和类不是编译时定义的,而是在运行时动态创建的
元类
metaclass,控制类的创建行为,metaclass是类的模板,必须从type类型派生,是对类的动态定义
谈谈Python中元类Metaclass(一):什么是元类 - 青山牧云人 - 博客园 (cnblogs.com)
def add(self,value):
self.append(value)
class ListMetaClass(type):
def __new__(cls,name,bases,attrs):
#cls: metaclass name
#name: 要构建的类的名称
print(f'__new__:cls={cls}, name={name}')#前者是元类的名称,后者是创建类的名称
attrs['add']=add
return type.__new__(cls,name,bases,attrs)
class Mylist(list,metaclass=ListMetaClass):#继承list类,并在list类中加入了一个方法add
pass
l=Mylist()
l.add(1)
l.add(2)
print(l)
抽象类借助abc模块实现
(11条消息) 31.Python中的抽象类 (Abstract Class)_bai666ai的博客-CSDN博客_python抽象类
class Plotter(abc.ABC):#构造抽象类Plotter
@abc.abstractmethod
def plot(self,*args,**kwargs):
pass
注册抽象类
@Abstract.register
虚拟子类
对于用户自定义的类型,即使不注册,抽象基类也能把一个是类别识别为虚拟子类
(14条消息) 同步调用,异步调用,回调_伏念先生的博客-CSDN博客
终于有人把进程与线程讲清楚了 - 知乎 (zhihu.com)简单通俗的原理
并行与并发:
**进程:**操作系统分配资源的基本单位
**线程:**CPU调度和分派的基本单位
应用程序至少有一个进程,一个进程至少有一个线程;进程分配内存,线程分配cpu(向cpu要时间?);同一个进程的多个线程可以并发执行;进程在执行过程中拥有独立的内存单元,而线程共享内存
线程的切换比进程切换的成本低,线程切换(多程序抢夺cup资源,内核态、用户态切换)。
同步&异步:同步和异步的区别 - 知乎 (zhihu.com)
临界资源&临界区:一次仅允许一个进程|线程使用,一个进程|线程进入临界区以后,其他的就需要等待,进入临界区的需要在有限时间内退出
**互斥量:**mutex是一个仅处于两态之一的变量:解锁/加锁
进程 process
**进程号:**os.getid()
**孤儿进程:**子进程在父进程退出后仍在运行,会被init进程接管,init以父进程的身份处理子进程完毕后遗留的状态信息
**僵尸进程:**父进程创建子进程后,若子进程退出,但父进程没有调用wait或waitoid获取子进程的状态信息,那么子进程的进程描述符将一直保存于系统,僵尸进程不能被kill来清除
(9条消息) Python–详细讲解僵尸进程与孤儿进程_千年乙方的博客-CSDN博客
一篇文章搞定Python多进程(全) - 知乎 (zhihu.com)
Python多进程运行——Multiprocessing基础教程1 - 知乎 (zhihu.com)
[Python程序中的进程操作-开启多进程(multiprocess.process) - 二十三岁的有德 - 博客园 (cnblogs.com)](https://www.cnblogs.com/nickchen121/p/11130256.html#:~:text=p.start (),:启动进程,并调用该子进程中的p.run ())
下面这个demo非常有意思,清楚的说明了多进程中start和join的作用
from multiprocessing import Process
import time
def fun1(name):
time.sleep(5)
print('测试%s多进程' %name)
if __name__ == '__main__':
process_list = []
for i in range(5): #开启5个子进程执行fun1函数
p = Process(target=fun1,args=('Python',)) #实例化进程对象
p.start()#启动一个子线程
process_list.append(p)
# for i in process_list:
# p.join()
time.sleep(1.5)#如果不加这个,多线成中,主线程的print先执行
print('结束测试')
开启子进程并在其中执行定制任务;提供process、queue、pipe、lock等关键组件;支持进程间的通信与数据共享;执行不同形式的同步;处理僵尸进程
process创建进程类,实例对象表示一个未启动的子进程
form multiprocessing import Process
#group参数未使用,target表示调用对象,子进程要执行的任务,后面就是一些参数,仅有一个参数的时候后面需要加逗号,name为子进程名称
p=Process(group=none,target=fun,name,*args,**kwargs)
#在windows中process()必须放到
if __name__=='__main__':
p.start()#表示启动进程,并且运行任务
p.run()
p.terminate()#强制终止进程
p.join(timeout)#主进程等待p终止,如果p进程未终止主进程不结束,timeout是可选的超时时间
p.daemon守护进程
使得子进程成为后台运行的守护进程,当p的父进程终止时,p也随之终止,且p不能创建新的子进程
from multiprocessing import Process
import time
import random
def task(name):
print('%s is piaoing' %name)
time.sleep(random.randrange(1,3))
print('%s is piao end' %name)
if __name__ == '__main__':
p=Process(target=task,args=('egon',))
p.daemon=True #一定要在p.start()前设置,设置p为守护进程,禁止p创建子进程,并且父进程代码执行结束,p即终止运行
p.start()
print('主') #只要终端打印出这一行内容,那么守护进程p也就跟着结束掉了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-biC1wEJq-1678455709919)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20221118181628001.png)]
同步vs异步同步、异步的使用场景及好处 - 一心二念 - 博客园 (cnblogs.com)
(14条消息) 并发、并行、串行、同步、异步的区别?_迷茫君的博客-CSDN博客
互斥锁[Python 互斥锁-Python threading Lock-嗨客网 (haicoder.net)](https://haicoder.net/python/python-thread-lock.html#:~:text= 互斥锁是传统并发编程对共享资源进行访问控制的主要手段,在 Python 中,threading 模块提供了相关互斥锁的操作,互斥锁的操作主要涉及到两个操作,即 acquire,和 release。 acquire 锁定当前的共享资源,release 进行解锁。 在使用互斥锁时,一定要注意:对资源操作完成后,一定要解锁,否则会出现流程执行异常,死锁等问题。)
每个资源都对应于一个可称为 “互斥锁” 的标记,这个标记用来保证在任意时刻,只能有一个线程访问该资源,其它的线程只能等待。
互斥锁是传统并发编程对共享资源进行访问控制的主要手段,在 Python 中,threading 模块提供了相关互斥锁的操作,互斥锁的操作主要涉及到两个操作,即 acquire 和 release。acquire 锁定当前的共享资源,release 进行解锁。
在使用互斥锁时,一定要注意:对资源操作完成后,一定要解锁,否则会出现流程执行异常,死锁等问题。
互斥锁的作用是用来保护共享资源的访问不出差错
信号量PYTHON——多线程:信号量(Semaphore) - 老π - 博客园 (cnblogs.com)
事件
条件
queue
[Python多进程队列(Queue)和生产者消费者模型 - PythonTechWorld](https://pythontechworld.com/article/detail/QQJDU0vFPtBa#:~:text=Python多进程队列(Queue)和生产者消费者模型 Python基础 队列,Python 多线程 多进程 Python中每个进程的内存是相互隔离的,那么如何实现进程之间的通信了,multiprocessing模块提供了队列和管道2种方式来实现进程之间的消息传递。)
(10条消息) 【python】详解queue队列(一)_brucewong0516的博客-CSDN博客_python中的队列
Python之【队列】常用操作及避坑指南 - 知乎 (zhihu.com)
from multiprocessing import Process,Queue
import time,random,os
def get_data(q,name):
while True:
data=q.get()
if data is None: # 获取结束信号,跳出死循环,不然等数据取玩了会一直卡在此处,is None很重要,不要用=None
break
time.sleep(random.randint(1,3))
print('%s 取出了 %s' %(name,data))
def create_data(q,name):
for i in range(5):
time.sleep(random.randint(1,3))
data='数据%s' %i
q.put(data)
print('%s 生产了 %s' %(name,data))
q.put(None) # 结束信号,不一定是None可以自己定义,就是告诉消费者已经停止生产数据了
if __name__ == '__main__':
q=Queue()
p1=Process(target=create_data,args=(q,"生产者")) #生产者
p1.start()
c1=Process(target=get_data,args=(q,"消费者")) #消费者
c1.start()
joinablequeue(maxsize)
python 并发编程 多进程 JoinableQueue - minger_lcm - 博客园 (cnblogs.com)
(9条消息) Python多进程之Pipe管道—进程之间数据通信_z-victor的博客-CSDN博客
(9条消息) python进程间通信之管道通信_wangdangduwamingood的博客-CSDN博客_python 管道通信
一般用于两个进程间的通信,但也可以用于多个进程,管道类似与一个队列,信息发出方一直发信息,形成一个队列,信息接收方按照发出的先后顺序接收信息
import multiprocessing import Process,Pipe
conn1,conn2=Pipe(duplex=True)#表示conn1,conn2都具有读写功能
conn1,conn2=Pipe()#表示conn1具有读的功能,conn2具有写功能,通信写在函数指令里。读,接受消息;写,发送消息。通道需要在产生于子进程之前
conn1.recv()#读,如果没有消息可接受,recv方法会一直阻塞,如果连接的一端已经关闭,那么recv方法会抛出EOFError,此时用conn1.close()关闭管道即可
conn2.send(data)#写
conn2.close()#当发送完了数据以后,关闭管道一端,另一端收到EOFError
from multiprocessing import Process, Pipe
import time
import os
import random
def receiver(conn,name):
#recv_c, send_c=conn
#send_c.close()#只用读端,关闭写端,注意windows有可能不能提前关闭
while True:
try:
message=conn.recv()
print("{} receives a message: {}".format(name,message))
except EOFError as eof:
conn.close()
break
def send(conn,name,messages):
#recv_c,send_c=conn
#recv_c.close() #只用写端,关闭读端,注意windows有可能不能提前关闭
for message in messages:
conn.send(message)
time.sleep(random.randint(1,2))
conn.close()
if __name__=='__main__':
messages=[]
with open('po.txt',"r",encoding="utf-8") as f:
for line in f:
messages.append(line.strip())
recv_con,send_con=Pipe()#在主进程中建立管道
printer=Process(target=receiver,args=(recv_con,'printer'))
printer.start()
sender=Process(target=send,args=(send_con,'sender',messages))
sender.start()
#注意windows建议仅在此处关闭
recv_con.close()
send_con.close()
sender.join()
print("所有消息发送完成...")
printer.join()
print('所有消息接收完成...')
以下的方法都需要加锁,只是开辟了一个共享内存空间,将数据映射到该空间上共进程处理
加锁有两种方法
from multiprocessing import Lock
lock=Lock()
lock.require()
block
lock.release()
------------
with lock:
block
–内存共享通过Value,Array类
python学习笔记——多进程中共享内存Value & Array (itxueyuan.com)
(14条消息) python多进程 - 进程间的通信(Queue,Pipe,Value/Array,Manager)_飞向天空的鹰的博客-CSDN博客
无非就是将原有的数据或数组之类的映射到一片内存空间用于共享,以免影响原数据,但是为了避免出错还是要枷锁的,这只是从共享内存空间上申请/创建一个具有c语言类型的数据对象给进程使用
##返回一个从共享内存上创建的ctypes对象
##从共享内存中申请并返回一个具有ctypes类型的数组对象
from multiprocessing import Process,Array
import time
def fun(m,n):
for i in range(n):
m[i]=i
m = Array('i',5)
p = Process(target= fun,args=(m,5))
p.start()
time.sleep(1)
for i in m:
print(i)
p.join()
–通过manager实现内存共享
manger返回的管理器对象控制一个服务进程,且由该进程保护python对象并允许其他进程通过代理操作对象。
返回的管理器支持类型支持value、Array、dict、list、Lock、Semaphore等等,同时Manager还可以共享类的实例对象。
manager=Manager()
dic=manager.dict()
–进程开启过多导致效率下降(同步,切换成本,减少进程创建和销毁的过程)
–应固定工作进程的数目
Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。
创建进程池:
form multiprocessing import Pool
Pool(numprocess,initializer,initargs)
--numprocess 要创建的进程数,默认使用os.cpu_count()的值
--initializer 每个工作进程启动时要执行的可调用对象,默认为None
--initargs 可调用对象的参数
p=Pool()
p.apply()
同步调用;只有一个进程执行(不并行);但可以直接得到返回结果(阻塞至返回结果)
apply(func, args=(), kwds={})
p.apply_async()
异步调用;并行执行,结果不一定马上返回;可以有回调函数:进程池中任意进程完成任务后会立即通知主进程,主进程将调用另一个函数去处理该结果,该函数即回调函数,其参数为返回结果
python在同一个线程中多次执行同一方法时,该方法执行耗时较长且每次执行过程及结果互不影响,如果只在主进程中执行,效率会很低,因此使用multiprocessing.Pool(processes=n)及其apply_async()方法提高程序执行的并行度从而提高程序的执行效率,其中processes=n为程序并行执行的进程数。
p.close()
关闭进程池
p.join()
等待所有工作进程退出,只能在close()或teminate()之后调用
补充:
回调函数的参数只有一个,即结果
回调参数由主进程调用
回调函数应该迅速结束
回调的顺序根子进程启动顺序无关
-p.map() 并行,主进程会等待所有子进程结束
-p.map_async() 并行,有回调函数
函数回调
进程池、线程池、回调函数 - 腾讯云开发者社区-腾讯云 (tencent.com)
可以在完成了函数以后直接回调,也可以在全部执行完统一执行
-对multiprocessing进一步抽象
-提供更简单、统一的接口
import concurrent.futures
from multiprocessing import current_process
import math
PRIMES = [
1112272535095293,
1112582705942171,
1112272535095291,
1115280095190773,
1115797848077099,
11099726899285419]
def is_prime(n):
print(f"{current_process().pid} is working on {n}")
if n % 2 == 0:
return False
sqrt_n = int(math.floor(math.sqrt(n)))
for i in range(3, sqrt_n + 1, 2):
if n % i == 0:
return False
return True
def main_submit():
results=[]
with concurrent.futures.ProcessPoolExecutor() as executor:
for number in PRIMES:
n_future=executor.submit(is_prime,number)
#print(n_future.result())#block
results.append(n_future)
#这里要注意,如果马上在主进程里获取结果,即n_future.result(),即主进程会阻塞,无法并行
#因此建议先将n_future搁进list,等启动所有进程后再获取结果。
for number, res in zip(PRIMES,results):
print("Result: %d is prime: %s" % (number,res.result()))
def main_map():
with concurrent.futures.ProcessPoolExecutor() as executor:
for number, prime_or_not in zip(PRIMES, executor.map(is_prime, PRIMES)):
print('%d is prime: %s' % (number, prime_or_not))
if __name__ == '__main__':
#main_submit()
main_map()
ProcessingPoolExecutor()生成一个进程池,然后直接将各参数依次传入,自动分配进程
submit()提交一个特定任务,返回一个实例--返回的实例结果需要用res.result(),如果马上调用这个结果会使得进程阻塞
map()批量提交函数,返回可迭代的结果对象
shutdown()关闭进程池
建议使用with,退出时自动调用shutdown()释放资源。
(14条消息) 【极客日常】python进程池ProcessPoolExecutor的用法与实现分析_utmhikari的博客-CSDN博客
(14条消息) Python ProcessPoolExecutor实践_Kevin9436的博客-CSDN博客_processpoolexecutor
分布式多进程
–多机环境
–跨设备数据交流
–如master-worker模型
–通过manager暴露queue
GIL(global inerpreter lock)
GIL非python特性,而是实现python解释器(cpython)时引入的概念
–GIL本质上是一个互斥锁
–GIL在解释器级保护共享数据
进程可以利用多核,但是开销大,而多线程开销小,但却无法利用多核
多进程从内存的角度看,线程是分配cpu
多进程用于计算密集型;多线程用于IO密集型,IO的特点不用cpu,重点在等待硬盘和网络上,而不涉及竞争GIL,如:爬虫同时发起网络请求
创建多线程----threading模块
Python 多线程 | 菜鸟教程 (runoob.com)
from threading import Thread,currentThread
import time
def task(name):
time.sleep(2)
print('%s print name: %s' %(currentThread().name,name))
class Task(Thread):
def __init__(self,name):
super().__init__()
self._name=name
def run(self):
time.sleep(2)
print('%s print name: %s' % (currentThread().name,self._name))
if __name__ == '__main__':
n=100
var='test'
t=Thread(target=task,args=('thread_task_func',))#通过制定target参数
t.start()
t.join()
t=Task('thread_task_class')#继承thread类方法
t.start()
t.join()
print('main')
线程同步:
···锁:
可重入锁,一旦线程获得了可重入锁,再次获取时将不阻塞
线程必须在每次获取后释放一次
区别在于:线程可以利用可重入锁,进行任务的递归调用
···信号量:
···事件:
···条件:当满足条件的时候,通知,很像观察者模式
python笔记11-多线程之Condition(条件变量) - 上海-悠悠 - 博客园 (cnblogs.com)
···定时器
···Barrier(栅栏):
某一特定位置,彼此等待,等待都到这一个位置后,再次并发执行
wait()方法来实现线程间的等待
–通过threading.loacl()创建
–线程在使用该类变量时会创建独立变量的拷贝
···queue.Queue
···queue.LifoQueue
···queue.PriorityQueue
python线程池 ThreadPoolExecutor 的用法及实战 - 简书 (jianshu.com)
#key表示返回最大值的方法,如key=dict.get,返回键
max(iterable, *[, key, default])
max(arg1, arg2, *args[, key])
Python3 filter() 函数 | 菜鸟教程 (runoob.com)
tuple与list互化
Python zip() 函数 | 菜鸟教程 (runoob.com)
菜鸟教程:Python3 字典 | 菜鸟教程 (runoob.com)
>>> confirm = {'a': 1, 'b': 2, 'c':3}
>>> dict_tuple = zip(confirm.keys(), confirm.values())
>>> type(dict_tuple)
<class 'zip'>
>>> for i in dict_tuple:
... print(type(i))
... print(i)
...
<class 'tuple'>
('a', 1)
<class 'tuple'>
('b', 2)
<class 'tuple'>
('c', 3)
>>> confirm = [('a', 1), ("b", 2), ("c", 3)]
>>> dict(confirm)
{'a': 1, 'b': 2, 'c': 3}
可以利用zip函数,使列表被打包,用来生成两列表的对应关系,其次对于zip的打印,需要转化为list。对于索引的调用,需要记住python索引不包括最后一位。
dic={}
dic[key]=dic.get(key,0)+1
用于生成一个字典,并且统计词频时使用,dict.get(key,default)函数表示当key存在时,返回键值,否则返回默认值default
提取键值对
dic={1:2,2:"ds",3:443}
print(list(dic.items()))
key=[]
value=[]
for item in list(dic.items()):
x,y=item
key.append(x)
value.append(y)
print(key)
print(value)
对键值大小排序
(3条消息) 【Python】按照字典中值的大小对键进行排序(lambda、sorted()、zip())_Vivid-victory的博客-CSDN博客
Python:Pandas创建Dataframe数据框的六种方法_AHU-丁少侠的博客-CSDN博客_python创建数据框
利用列表生成数据框
菜鸟教程:Python3 输入和输出 | 菜鸟教程 (runoob.com)
__ name __ 属于内建变量
__ name __内置变量表示当前调用的模块是否在本模块里运行,如果在test.py内测试,则打印“在本模块内调用”;如果在其他模块中调用test.py则打印“在模块外调用”。在调用模块的时候注意不能加入.py的后缀
#文件为test.py
if __name__=="__main__":
print("在本模块内调用")
else:
print("在模块外调用")
模块仅被导入一次,多次调用模块也只出现一次“在模块外调用”
dir(module)返回定义在模块内的所有名称
包
包中有目录,且每个保重必须有__ init __.py才被视为一个包
包是一个含有__ init __.py文件的文件夹,这个py文件本身不需要具有含义,注意init文件为双下滑线。以下为文件夹的形式,注意对于模块的调用必须一次到位,调用到模块,如果说之import了package包,是无法正常使用的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v1Oewzrf-1678455709921)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20220923191941378.png)]
import package.package_2.one as R
R.x()
使用R.reload(x)用来更新x模块,因为import只解释一次,在交互式情况下可以使用该函数
在模块的调用时,可以通过对目录内添加某些文件对其进行优化。
在调用函数时,我发现,当我不对函数添加括号时,跳出来了一串地址,是因为此时调用了函数本身,返回函数对象,无需等结果运行出来。
当对函数添加括号时,返回的是函数的调用结果。
(11条消息) Python函数的可变长参数_Python 学习者的博客-CSDN博客_python函数可变长参数
可变长度参数 : *a表示一个可变长度的元组参数,**b表示一个可变长度的字典,在导入参数的时候可以参照以下例子
def func(*a,**b):
print(a)
print(b)
func(1,2,'x'=1,'y'=2)
'''
(1,2)
{'x':1,'y':2}
'''
菜鸟教程:Python3 面向对象 | 菜鸟教程 (runoob.com)
W3 school:Python 类和对象 (w3school.com.cn)
比较好使的:Python类和对象 (biancheng.net)
类对象支持两种操作:属性引用和实例化
类对象创建后,类命名空间中的所有属性都是有效属性名。实例化类,创建一个类的对象。在类的定义中,self表示一个类的实例。实例对象只能对数据或者方法进行引用。
对象的状态:当下实例域的值的特定组合。
类的方法:在类的内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为第一个参数,self 代表的是类的实例。
类的私有方法只能在类内调用,而不能在类外调用。__ init __() 函数始终在启动类时,使用该函数将值赋给对象属性,或者在创建对象时需要执行的其他操作。私有方法在类内部使用
#self指的时未来在调用类时的一个实例,对于每个类基本上都会设置该函数
class Person:
ID=0#类属性,属于类本生,与实例无关
def __init__(self, id,name, major):#如果没有实例化,是不会产生下方属性的
self.__name = name#私用属性,不希望外部调用
self.__major = major
self.__id=id
def set_major(self,new_major):#函数里调用时需要使用self.parameter
self._major=new_major
def get_name(self):
return self.__name
def main():
s1=Person(33,"lb","MIS")#构建了一个实例s1,自动作为self传入
s1.set_major("cs")
print(s1.get_name())#由调用可见,这种私用属性的调用是不希望出现的
print(s1.__name)#这一步会报错,因为该属性被改变,使得找不到路径
类有私有属性,在前面加一个__双下划线,私有属性只能在类内使用,不能在类外随意调用,貌似类外调用类内属性会被伪装。
*xx: 公有变量
_x: 单前置下划线,私有化属性或方法,from somemodule import 禁止导入,类对象和子类可以访问
_xx:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到)
xx:双前后下划线,用户名字空间的魔法对象或属性。例如:init , __ 不要自己发明这样的名字
xx:单后置下划线,用于避免与Python关键词的冲突
通过name mangling(名字重整(目的就是以防子类意外重写基类的方法或者属性)如:_Class__object)机制就可以访问private了。
类的数据属性,默认情况下通过字典__ dict __ 维护数据属性。Python 中的 类,都会从 object 里继承一个 dict 属性,这个属性中存放着类的 属性 和 方法 对应的键值对。一个类 实例化 之后,这个类的实例也具有 dict 属性。Python 类中的 __ dict __ 属性是以 字典 的形式存放着属性和方法,键为属性名,值为属性的值。
>>> class A(object):
... a = 0
... b = 1
... def __init__(self):
... self.a = 2
... self.b = 3
... def test(self):
... print("a normal func.")
...
... @staticmethod
... def static_test(self):
... print("a static func.")
...
... @classmethod
... def class_test(self):
... print("a class func.")
...
>>> obj = A()
>>> print(A.__dict__)
{'__module__': '__main__', 'a': 0, 'b': 1, '__init__': <function A.__init__ at 0x10b5f61e0>, 'test': <function A.test at 0x10b5f6268>, 'static_test': <staticmethod object at 0x10b5f16d8>, 'class_test': <classmethod object at 0x10b5f1748>, '__dict__': <attribute '__dict__' of 'A' objects>, '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None}
>>>
>>> print(obj.__dict__)
{'a': 2, 'b': 3}
Python new()方法详解 (biancheng.net)
new() 是一种负责创建类实例的静态方法,它无需使用 staticmethod 装饰器修饰,且该方法会优先 init() 初始化方法被调用。
将实例变为可调用对象
(11条消息) python类中的 call()方法运用_我是天才很好的博客-CSDN博客
class Log:
def __init__(self,logfile='out.log'):
self.logfile=logfile
def __call__(self,func):
@wraps(func)
def wrapper(*args,**kwargs):
info="INFO: "+func.__name__+" was called"
with open(self.logfile,'a') as file:
file.write(info+'\n')
return func(*args,**kwargs)
return wrapper
@Log('test.log')
def myfunc():
pass
myfunc()#等价于log('test.log')(myfunc)() 其中表示将实例变为可调用的函数
python 类中的私有属性和方法 - 知乎 (zhihu.com)
类内调用类内函数
(8条消息) python中class(类)的使用,类的教程,类中的函数怎么调用。_狗风暴的博客-CSDN博客_python调用class
类名.函数名
self.函数名
cls
[(8条消息) python 中的self和cls_GTFQAQ的博客-CSDN博客_python中cls和self](https://blog.csdn.net/gtf215998315/article/details/106868558?ops_request_misc=%7B%22request%5Fid%22%3A%22166652375416782427492243%22%2C%22scm%22%3A%2220140713.130102334.pc%5Fall.%22%7D&request_id=166652375416782427492243&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-4-106868558-null-null.142v59pc_rank_34_queryrelevant25,201v3control_2&utm_term=类 cls&spm=1018.2226.3001.4187)
重点关注super(). __ init __()用于继承父类的初始化,非常重要
继承其他类的类称为派生类,被其它类继承的类被称为这些类的基类。
继承语法:
class derivedclassname(modname.baseclassname):#从任意模块继承一个类
#类定义
class people:
#定义基本属性
name = ''
age = 0
#定义私有属性,私有属性在类外部无法直接进行访问
__weight = 0
#定义构造方法
def __init__(self,n,a,w):
self.name = n
self.age = a
self.__weight = w
def speak(self):
print("%s 说: 我 %d 岁。" %(self.name,self.age))
#单继承示例
class student(people):
grade = ''
def __init__(self,n,a,w,g):
#调用父类的构函
people.__init__(self,n,a,w)
self.grade = g
#覆写父类的方法
def speak(self):
print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade))
s = student('ken',10,60,3)
s.speak()
#####甚至可以继承多个类
#另一个类,多重继承之前的准备
class speaker():
topic = ''
name = ''
def __init__(self,n,t):
self.name = n
self.topic = t
def speak(self):
print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic))
#多重继承
class sample(speaker,student):
a =''
def __init__(self,n,a,w,g,t):
student.__init__(self,n,a,w,g)
speaker.__init__(self,n,t)
test = sample("Tim",25,80,4,"Python")
test.speak() #方法名同,默认调用的是在括号中参数位置排前父类的方法
派生类可能会覆盖其基类的方法
(3条消息) Python基础:super()用法_硝烟_1994的博客-CSDN博客_python super()
super() 函数是用于调用父类(超类)的一个方法。
super() 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。
MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。
class X(object):pass
class Y(object):pass
class A(X, Y):pass
class B(Y):pass
class C(A, B):pass
print C.__mro__
# (, ,
# , ,
# , )
##查找顺序
(3条消息) Python 魔法方法(六) 从__mro__ 了解类多继承顺序和原理_yusuiyu的博客-CSDN博客
class A:
def __init__(self):
self.n = 2
def add(self, m):
print('self is {0} @A.add'.format(self))
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
print('self is {0} @B.add'.format(self))
super().add(m)
self.n += 3
class C(A):
def __init__(self):
self.n = 4
def add(self, m):
print('self is {0} @C.add'.format(self))
super().add(m)
self.n += 4
class D(B, C):
def __init__(self):
self.n = 5
def add(self, m):
print('self is {0} @D.add'.format(self))
super().add(m)#对父类的函数直接调用,此时没有重新初始化,调用顺序为D,B,C,A
self.n += 5
d = D()
d.add(2)
print(d.n)
out:
self is <__main__.D object at 0x10ce10e48> @D.add
self is <__main__.D object at 0x10ce10e48> @B.add
self is <__main__.D object at 0x10ce10e48> @C.add
self is <__main__.D object at 0x10ce10e48> @A.add
19
(3条消息) Python - Object类_星小白的博客-CSDN博客_python类object
所有类的父类,默认所有的类都继承至object父类,如果有父类才编写,如果没有父类可以省略
(3条消息) python之运算符重载_zsj.python之路的博客-CSDN博客_python重载运算符
(3条消息) 浅析Python运算符重载_viclee108的博客-CSDN博客_python 重载比较运算符
工厂模式依然是一种创建型设计模式,作为工厂,它所关心的是产品的产生,也就是对象的创建,我们利用工厂来创建对象,而不必我们亲自创建对象,我们无需去理解如何创建对象,只需要向工厂提出要求,让工厂去根据你的要求,给你生产你要的产品,给你相应的对象,这种模式便叫做工厂模式。
Python实现设计模式——工厂模式 - 骑鱼嘚猫 - 博客园 (cnblogs.com)
(6条消息) python : 自定义可迭代类,iter ,__next__的作用_wzg2016的博客-CSDN博客_python iter
class Numbers:
def __init__(self,start=1,step=1,max=100):
self._start=start
self._step=step
self._max=max
self._a=self._start
#self._list=[]
def __iter__(self):
return self
#return iter(self._list)
def __next__(self):
if self._a <= self._max:
x = self._a
self._a += self._step
return x
else:
raise StopIteration('大于max:{}'.format(self._max))
num=Numbers(start=2,step=2,max=100)
myiter=iter(num)
print(myiter)
# for x in num:
# print(
iter 和 next 方法是python中约定好的,定义以上两种函数就表示这是一个可迭代的类
1)通过在类中添加 __iter__函数,向系统说明这是一个可迭代对象。
2)通过在类中添加 __next__函数,向系统提供该可迭代对象的迭代算法
3)在代码执行过程中,for循环函数会自动检查系统信息,识别__iter__函数,然后自动调用对应的__next__函数,生成一个迭代器。
4)所以在定义一个可迭代类时,一般__iter__ 函数要与 __next__函数成对出现。__iter__函数向系统声明这个类可迭代,__next__定义了具体的迭代器。
5)iter 与 __next__两个函数名不可改变,否则系统会不识别。
6)__next__函数的 return 在 if 判别命令的内部,每次执行__next__函数时,单次判别后直接输出。不满足判别条件时输出迭代终止。
(5条消息) Python Pandas中dataframe常用操作(创建、读取写入、切片等)_Parzival_的博客-CSDN博客_python 写入dataframe
(5条消息) python做数据分析时缺失值填补、缺失值填充方法汇总_theskylife的博客-CSDN博客_python对某一列填充某个值
(5条消息) Python Pandas找到缺失值的位置_kevinorg123的博客-CSDN博客_pandas查找缺失值
pandas和numpy联合使用:numpy使用的是np.where返回标签序号
生成词云的方法
import jieba
from wordcloud import WordCloud
import matplotlib.pyplot as plt
from PIL import Image #处理图片的
import numpy as np
#创建分词词典,读入分词词典的词是按行读入的
jieba.load_userdict(path1)
#对文本导入并且进行分词
with open(path2) as f:
lis=f.read()
cut=jieba.lcut(lis,cut_all=False)
#对文本进行清洗
stopword=[]
with open(path1) as f:
stopword=[i.strip() for i in f.readlines()]
filter=[]
for item in cut:
if cut in stopword:
continue
filter.append(cut)
#统计词频,并且从大到小排序
cipin={}
for item in filter:
cipin[item]=cipin.get(item,0)+1
items=list(cipin.items())
items.sort(key=lambda x: x[1], reverse=True)
cipin=dict(items)
cipin_n=dict(items[0:n])#取前n个高频词
#生成词云
im=Image.open(path3)#导入图片
im=np.array(im)#格式化图片
wc=WordCloud(background_color='white',
mask=im,#设置词云的背景
font_path = 'msyh.ttc',
width=1000, height=860,
margin=2)
#使用文本生成词云
filter=" ".join(filter)
wc.generate(filter)
#使用字典生成词云
wc.generate_from_frequencies(cipin)
#显示并保存词云
plt.imshow(wc,interpolation="bilinear")#将数组值转化为图片展示,显示图像的插值方法bilinear
plt.axis("off")
wc.to_file('./wordcloud.png')
(5条消息) python做数据分析时缺失值填补、缺失值填充方法汇总_theskylife的博客-CSDN博客_python对某一列填充某个值
(5条消息) python中csv文件的创建、读取、修改等操作总结_m0_46483236的博客-CSDN博客_python读csv文件并修改
Pillow - 教程 - 蝴蝶教程 (jc2182.com)
Python常用标准库之datetime模块 - 知乎 (zhihu.com)
官网教程及例子:教程 — NetworkX 2.8 文档 (osgeo.cn)
csdn博客:[(社会网络分析与挖掘—Python之networkx介绍_Machanical-Thinking的博客-CSDN博客_networkx计算网络指标](https://blog.csdn.net/qq_34302921/article/details/80726448?ops_request_misc=&request_id=&biz_id=102&utm_term=python networkx&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-1-80726448.nonecase&spm=1018.2226.3001.4187)
Python NetworkX_hxxjxw的博客-CSDN博客
**图边等方法的汇总:【NetWorkX实例(3)】图、边、节点等相关方法_LotusQ的博客-CSDN博客**
networkx是一个python包,用于创建、操作和研究复杂网络的结构、动态和功能。使用NetworkX,可以以标准和非标准数据格式加载和存储网络,生成多种类型的随机和经典网络,分析网络结构,构建网络模型,设计新的网络算法,绘制网络。
一般networkx会与matlplotlib包一起使用,用来做构建与可视化。
导入库
import networkx as nx
create graph
import networkx as nx
import matplotlib.pyplot as plt#注意matplotlib里有子目录pyplot
G=nx.Graph()#创建空白图
G.add_node(1)#增加一个节点,名字叫做1
G.add_node("A")#增加一个叫做A的节点
G.add_nodes_from([2,3])#增加节点组,2和3
nx.draw(G,with_labels=True)#绘制G的labels
plt.show()
create edge
G.add_edge(2,"A")#连接节点2和A
G.add_edges_from([(1,2),(1,3),(2,"A"),(2,3)])#添加多条边
为节点添加属性
sf
可视化:用networkx做网络关系可视化 - 简书 (jianshu.com)
networkx 画图布局_ACxz的博客-CSDN博客_networkx画图
**关于图的一些知识:**
图的密度: d e n s i t y = e d g e s n o d e × ( n o d e − 1 ) density=\frac{edges}{node\times(node-1)} density=node×(node−1)edges
只有一个播放功能
from playsound import playsound
playsound('/path/to/a/sound/file/you/want/to/play.mp3')
(9条消息) python 遍历多级目录下文件的方法_weixin_34390996的博客-CSDN博客
Python OS 文件/目录方法 | 菜鸟教程 (runoob.com)
使用遍历结构,将文件夹及其子文件夹里的所有文件路径保存
path_lis=[]
for root, dirs, names in os.walk(path): # 当读入的是文件夹时,则将文件夹力的文本都读入
for filename in names:
path_lis.append(os.path.join(root, filename))
#这是一个图片路径列表
path_lis
#读取图片,并将图片数据存在列表中
pic=[]
for im in self.path:
io=Image.open(im)
io=io.resize((300,400))
pic.append(io)
imageio.mimsave("./GIF.gif",pic,'gif',duration=0.3, loop=0)#参数duration表示每一帧间隔的秒数,loop表示循环次数,0表示无限循环
Python JSON | 菜鸟教程 (runoob.com)
json.dump()
json.load()
#积累为主
#####1
a="Fri Oct 11 23:31:07 +0800 2013"
match=re.sub(r"\+\d{4}","",a)##匹配了+0800,\+表示匹配+,\d{4}表示匹配任意数字,且长度为4
#####2
.*表示匹配0或多个非回车的任意字符
####
{}内表示匹配的次数,{1,4}表示匹配1到4次;{1,}表示匹配至少1次;{3}匹配3次
####
[xad]表示匹配含有xad内的字符的;[^xad]表示匹配不含有xad内的字符的
####123.123.123.223
()用于分组
常用于表示IP地址 形如: ((25[0-5]|2[0-4][0-9]|[0-1]\d\d)\.){3}(25[0-5]|2[0-4][0-9]|[0-1]\d\d)
首先分为了两部分,第一部分123.123.123. 第二部分为123;;;第一部分(){3}表示该分组重复匹配3次,表示从0到255,\.表示将.转义,\d表示任意数字,后一部分表示200到255,|表示或者,&表示与
菜鸟教程:https://www.runoob.com/python3/python3-dictionary.html
(3条消息) 正则表达式全解析+常用示例_墨遥的博客-CSDN博客_正则表达式解析
正则表达式 – 语法 | 菜鸟教程 (runoob.com)
正则应用之——日期正则表达式 - Boblim - 博客园 (cnblogs.com)
解释:match对象
match对象的方法:
.group(0) : 获得匹配后的字符串
.start() : 匹配字符串在给定字符串的开始位置下标
.end() : 匹配字符串在给定字符串的结束位置下标
.span() : 返回一个元组类型,包含开始位置下标和结束位置下标
对于正则表达式,一般使用re库,re库有以下常用的函数
返回第一个匹配的位置,返回match对象
flags参数表示正则表达式使用使得控制标记:re.I 忽略正则表达式的大小写,匹配小写字符; re.M ;re.S匹配所有的字符串; 0为默认?
从字符串的开头开始匹配,如果第一个字符匹配不上,则无法匹配到
以列表类型返回字符串里所有能够匹配的字串
maxsplit指的是最大分割数,剩余部分作为最后一个元素输出,指的是割一次,如为1时,则分成两块。
repl:替换匹配字符串的字符串
count: 匹配时的最大替换次数,默认为全部替换
match = re.sub(r'[1-9]\d{5}', ':sucode', 'shenzhen 518000 shenzhen123456')
# subApiDemo:shenzhen :sucode shenzhen:sucode
print("subApiDemo:" + match)
搜索字符串,返回皮欸结果的迭代类型,每个迭代元素是match对象
"""
re.finditer(pattern, string, flags=0)
搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是match对象
- pattern: 正则表达式的字符串或原生字符串表示
- string:待匹配字符串
- flags:正则表达式使用时的控制标记
"""
def finditerApiDemo():
# 返回的是一个列表
matchIter = re.finditer(r'[1-9]\d{5}', 'shenzhen 518000 shenzhen123456')
for m in matchIter:
if m:
# finditerApiDemo:518000
# finditerApiDemo:123456
print("finditerApiDemo:" + m.group(0))
将正则表达式编译程正则表达式的对象
def compileApiDemo():
regex = re.compile(r'[1-9]\d{5}')
match = regex.search('shenzhen518000')
if match:
# compileApiDemo - search:518000
print('compileApiDemo - search:' + match.group(0))
match = regex.match('518000shenzhen')
if match:
# compileApiDemo - match:518000
print('compileApiDemo - match:' + match.group(0))
教程汇总:Gephi教程汇总 - 知乎 (zhihu.com)
[(5条消息) Py-plt:Plot如何控制坐标轴,图例和注释画出精美的图_MyName_Guan的博客-CSDN博客_pyplot 坐标轴](https://blog.csdn.net/MyName_Guan/article/details/109913864?ops_request_misc=%7B%22request%5Fid%22%3A%22166580286216782390540557%22%2C%22scm%22%3A%2220140713.130102334…%22%7D&request_id=166580286216782390540557&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-109913864-null-null.142v56pc_rank_34_queryrelevant25,201v3control_2&utm_term=python plot函数坐标轴设置&spm=1018.2226.3001.4187)
平时可以用的可视化图片:线图、饼图、热力图、地图、河流图、树形矩阵等。
python可视化最常用的11个分布图:python可视化48|最常用11个分布(Distribution)关系图 - 知乎 (zhihu.com)
python曲线图可视化:[Python数据可视化:如何创建曲线图 - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/166526796#:~:text=Python数据可视化:如何创建曲线图 1 1. 基础线图 使用matplotlib创建图形的四个基本步骤: 准备数据 … 2,4. 添加标题,坐标轴标签和图例 优秀的可视化要传递有效的信息,有一些图形元素必不可少,例如标题,坐标轴标签,如果有多条曲线,为每条曲线添加标签是合理的。 … 5 5. 同时调整多个样式 )
一般调用plt的语句为import matplotlib.pyplot as plt
[plt: subplot()、subplots()详解及返回对象figure、axes的理解_涛涛ALG的博客-CSDN博客_subplots返回值](https://blog.csdn.net/sunjintaoxxx/article/details/121098302?ops_request_misc=%7B%22request%5Fid%22%3A%22166402904516782427479642%22%2C%22scm%22%3A%2220140713.130102334…%22%7D&request_id=166402904516782427479642&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-121098302-null-null.142v50control,201v3control_2&utm_term=python subplot返回值&spm=1018.2226.3001.4187)
#关于subplot的返回值
fig,ax=plt.subplot(2,2)
figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True)
num:图像编号或名称,数字为编号 ,字符串为名称
figsize:指定figure的宽和高,单位为英寸;
dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80 1英寸等于2.5cm,A4纸是 21*30cm的纸张
facecolor:背景颜色
edgecolor:边框颜色
frameon:是否显示边框
[(3条消息) python plt.show_python plt.show 关闭_weixin_39625429的博客-CSDN博客](https://blog.csdn.net/weixin_39625429/article/details/111731839?ops_request_misc=%7B%22request%5Fid%22%3A%22166516345816782428690292%22%2C%22scm%22%3A%2220140713.130102334.pc%5Fall.%22%7D&request_id=166516345816782428690292&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-111731839-null-null.142v51control,201v3control_2&utm_term=python plt.show自动关闭&spm=1018.2226.3001.4187)
知乎:python绘图-seaborn绘图的基本使用 - 知乎 (zhihu.com)
箱型图绘制:(3条消息) Seaborn绘制箱型图_尤尔小屋的猫的博客-CSDN博客_seaborn 箱线图
distplot建议不要用,貌似以后会弃用,这个函数真nm坑
官方网站:seaborn.displot — seaborn 0.12.0 documentation (pydata.org)
热力图
(5条消息) python画出热力图,热力图数值,修改字体,字体大小等_bai_bai123的博客-CSDN博客
饼图
[(5条消息) 用python实现PyEcharts中的饼图_不太累的码农的博客-CSDN博客](https://blog.csdn.net/weixin_52720197/article/details/114749080?ops_request_misc=&request_id=&biz_id=102&utm_term=python pychart绘制饼图&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-3-114749080.142v56pc_rank_34_queryrelevant25,201v3control_2&spm=1018.2226.3001.4187)
[(5条消息) pyecharts画饼形图,圆形图,环形图(含百分比显示)【python干货】_写python的鑫哥的博客-CSDN博客_pyecharts圆饼图](https://blog.csdn.net/Leexin_love_Ling/article/details/109572049?ops_request_misc=&request_id=&biz_id=102&utm_term=python pyrchart 饼图显示比例&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-9-109572049.142v56pc_rank_34_queryrelevant25,201v3control_2&spm=1018.2226.3001.4187)
图表 API - pyecharts - A Python Echarts Plotting Library built with love.
Document (pyecharts.org)这个是最新的,里面的代码可以使用,上面那个貌似版本太老了,但是可以学习参数
配置设置
pyechart的属性都是通过options配置的,具体可查看下方连接的参数配置
(6条消息) 【宝藏级】PyEcharts 超详细的使用指南_普通网友的博客-CSDN博客_pyecharts详细教程
from pyecharts import options as opts
#初始化图的主题
Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
#全局配置
.set_global_opts(里面填写下方的参数)
title_opts=opts.TitleOpts(title=,subtitle)#标题配置项,
添加x,y轴数据
.add_xaxis(添加数据种类数n)
.add_yaxis(添加一个数据集名称,添加该数据集中的n个数据)#可add_yaxis多个
保存为html
.render()
(5条消息) Python轻松实现地图可视化(附详细源码)_普通网友的博客-CSDN博客_python 画自建房地图
爬虫基本流程:1.发起请求:
通过HTTP库向目标站点发起请求,即发送一个Request,请求可以包含额外的headers、data等信息,然后等待服务器响应。这个请求的过程就像我们打开浏览器,在浏览器地址栏输入网址:www.baidu.com,然后点击回车。这个过程其实就相当于浏览器作为一个浏览的客户端,向服务器端发送了 一次请求。
2.获取响应内容:
如果服务器能正常响应,我们会得到一个Response,Response的内容便是所要获取的内容,类型可能有HTML、Json字符串,二进制数据(图片,视频等)等类型。这个过程就是服务器接收客户端的请求,进过解析发送给浏览器的网页HTML文件。
3.解析内容:
得到的内容可能是HTML,可以使用正则表达式,网页解析库进行解析。也可能是Json,可以直接转为Json对象解析。可能是二进制数据,可以做保存或者进一步处理。这一步相当于浏览器把服务器端的文件获取到本地,再进行解释并且展现出来。
4.保存数据:
保存的方式可以是把数据存为文本,也可以把数据保存到数据库,或者保存为特定的jpg,mp4 等格式的文件。这就相当于我们在浏览网页时,下载了网页上的图片或者视频。
import urllib.request
#获取一个get请求
response=urllib.request.urlopen(path)#获取网页信息
response.read().decode("utf-8")#读取数据,并解码
#获取post请求
#测试网址httpbin.org
伪装成浏览器
Python爬虫:HTML网页解析方法小结 - 知乎 (zhihu.com)
(15条消息) Beautiful Soup的用法(五):select的使用_go2coding的博客-CSDN博客ccs解析方法
Python 内置了 requests 模块,该模块主要用来发 送 HTTP 请求,requests 模块比 urllib 模块更简洁
requests.session() 就派上用场了,它可以自动处理cookies,做状态保持。
# 先实例化一个对象
session = requests.session()
# 后面用法和直接使用requests一样了
response = session.get(url) # get请求
response = session.post(url, json=json_data) # post请求
result = response.json()
(55条消息) requests 模块的 requests.session() 功能_python编程的博客-CSDN博客
.content 返回的是可以自由加工的(以你想要的编码格式来进行编码)的字节串,是只高于二进制数据的一种数据存储单位。用于保存视频、音频文件时,用于的读取方式。
命令行运行python
python 文件路径 参数
本地连接的测试ip为127.0.0.1
(15条消息) 几个特殊的IP地址_阿斐要拯救世界的博客-CSDN博客_特殊的ip地址有哪些
socket是一个API接口,Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。通过一个 Socket 实例唯一代表一个主机上的一个应用程序的通信链路了。
[TCP、Socket、WebSocket、HTTP - 知乎 (zhihu.com)](https://zhuanlan.zhihu.com/p/51279572#:~:text=Socket是对TCP%2FIP协议的封装,像创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议 (TCP或UDP)%2C当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。,1. Polling 这种方式就是通过Browser%2FUA定时的向Web服务器发送http的Get请求,服务器收到请求后,就把最新的数据发回给客户端(Browser%2FUA),Browser%2FUA得到数据后,就将其显示出来,然后再定期的重复这一过程。)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nq3sjtKn-1678455709923)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20221125182347097.png)]
客户端开发的流程
创建socket、和服务器建立连接、发送数据、接收数据、结束通讯、关闭套接字
from socket import *
"""
family: 表示IP地址类型, 分为TPv4和IPv6。AF_INET6表示IPV6 ,AF_INET表示ipv4
type:表示传输协议。SOCK_STREAM表示TCP协议,SOCK_DGRAM表示UDP协议
具体这些参数还有哪些可选择的值,请参考:https://docs.python.org/zh-cn/3/library/socket.html
"""
#"localhost":在计算机网络中,localhost(意为“本地主机”,指“这台计算机”)是给回路网络接口(loopback)的一个标准主机名,相对应的IP地址为127.0.0.1(IPv4)和[::1](IPv6)
client=socket(AF_INET,SOCK_STREAM)
#建立连接,建立连接的socket为client,这是一条客户端与服务端一对一的联系
client.connect((服务端ip,服务端端口号))
#发送数据,str表示的是发送的文本信息
client.send(str.endcode("utf-8"))
#接收信息,表示接收端一次最多接收1024个字节的信息,MTU为1500字节
recv_data=client.recv(1024)
#对数据进行解码
print("recv:", recv_data.decode("utf8"))
#结束连接
client.close()
服务端开发流程
创建socket,绑定端口号(可设置端口可重用)、设置监听、等待客户端连接,收到连接后,返回一个为本次服务的socket和其他地址元组、接收数据、返回数据、当读到客户端的连接关闭时,关闭本次连接的socket,结束通讯、关闭服务(不一定)
form socket import *
#在服务器端,socket()返回的套接字用于监听(listen)和接受(accept),这个套接字不能用于与客户端之间发送和接收数据。
sever=socket(AF_INET,SOCK_STREAM)
sever.bind((服务器ip,服务器端口号))#绑定之后,就不能再生成另一个套接字了
"""
参数说明:
level:操作socket的级别,若要在API级别操作,选择SOL_SOCKET
option:操作项,这里是SO_REUSEADDR 标志告诉内核将处于 TIME_WAIT 状态的本地套接字重新使用,而不必等到固有的超时到期
value:用于访问setsockopt()的选项值,文档里面是默认给1或者True
"""
server.setsocket(SOL_SOCKET,SO_REUSERADDR,1)
#设置监听,128是最大连接数
server.listen(128)
while True:#如果有多个client同时发起请求,阻塞,一个个来
#等待客户端连接,收到连接后会返回一个专门服务于本次连接的socket和一个地址元组address
#accept()接受一个客户端的连接请求,并返回一个新的套接字,不同于以上socket()返回的用于监听和接受客户端的连接请求的套接字;与此客户端通信是通过这个新的套接字上发送和接收数据来完成的。
client_socket,address=server.accept()#address是自动分配的接口
recv_data=client_socket.recv(1024)#利用专门负责客户端通信的socket进行,此时负责监听的socket套接字可以关闭
client_socket.send("hello")
client_socket.close()
sever.close()#如果需要的化
注意对于服务端端口是自己设定的,对于客户端的端口是系统分配的
多人聊天的方式:
sever端打开监听socket,
server端接收到一个客户端,建立一个socket与客户端建立起单独的联系,建立一个线程专门负责该客户端
相比于TCP socket这个方法有以下不同:
不许建立连接
无需任何准备就可以进行数据传输
头部开销小
但是连接不可靠
UnboundLocalError: local variable ‘args’ referenced before assignment:变量未被正确引用,找不到,未赋值
1、学习pyechart orz
2、系统完整的学习装饰器的各类用法
3、ffmpeg配不好
4、os路径走法
5、虚拟子类
lan.zhihu.com/p/51279572#:~:text=Socket是对TCP%2FIP协议的封装,像创建Socket连接时,可以指定使用的传输层协议,Socket可以支持不同的传输层协议 (TCP或UDP)%2C当使用TCP协议进行连接时,该Socket连接就是一个TCP连接。,1. Polling 这种方式就是通过Browser%2FUA定时的向Web服务器发送http的Get请求,服务器收到请求后,就把最新的数据发回给客户端(Browser%2FUA),Browser%2FUA得到数据后,就将其显示出来,然后再定期的重复这一过程。)
[外链图片转存中…(img-nq3sjtKn-1678455709923)]
客户端开发的流程
创建socket、和服务器建立连接、发送数据、接收数据、结束通讯、关闭套接字
from socket import *
"""
family: 表示IP地址类型, 分为TPv4和IPv6。AF_INET6表示IPV6 ,AF_INET表示ipv4
type:表示传输协议。SOCK_STREAM表示TCP协议,SOCK_DGRAM表示UDP协议
具体这些参数还有哪些可选择的值,请参考:https://docs.python.org/zh-cn/3/library/socket.html
"""
#"localhost":在计算机网络中,localhost(意为“本地主机”,指“这台计算机”)是给回路网络接口(loopback)的一个标准主机名,相对应的IP地址为127.0.0.1(IPv4)和[::1](IPv6)
client=socket(AF_INET,SOCK_STREAM)
#建立连接,建立连接的socket为client,这是一条客户端与服务端一对一的联系
client.connect((服务端ip,服务端端口号))
#发送数据,str表示的是发送的文本信息
client.send(str.endcode("utf-8"))
#接收信息,表示接收端一次最多接收1024个字节的信息,MTU为1500字节
recv_data=client.recv(1024)
#对数据进行解码
print("recv:", recv_data.decode("utf8"))
#结束连接
client.close()
服务端开发流程
创建socket,绑定端口号(可设置端口可重用)、设置监听、等待客户端连接,收到连接后,返回一个为本次服务的socket和其他地址元组、接收数据、返回数据、当读到客户端的连接关闭时,关闭本次连接的socket,结束通讯、关闭服务(不一定)
form socket import *
#在服务器端,socket()返回的套接字用于监听(listen)和接受(accept),这个套接字不能用于与客户端之间发送和接收数据。
sever=socket(AF_INET,SOCK_STREAM)
sever.bind((服务器ip,服务器端口号))#绑定之后,就不能再生成另一个套接字了
"""
参数说明:
level:操作socket的级别,若要在API级别操作,选择SOL_SOCKET
option:操作项,这里是SO_REUSEADDR 标志告诉内核将处于 TIME_WAIT 状态的本地套接字重新使用,而不必等到固有的超时到期
value:用于访问setsockopt()的选项值,文档里面是默认给1或者True
"""
server.setsocket(SOL_SOCKET,SO_REUSERADDR,1)
#设置监听,128是最大连接数
server.listen(128)
while True:#如果有多个client同时发起请求,阻塞,一个个来
#等待客户端连接,收到连接后会返回一个专门服务于本次连接的socket和一个地址元组address
#accept()接受一个客户端的连接请求,并返回一个新的套接字,不同于以上socket()返回的用于监听和接受客户端的连接请求的套接字;与此客户端通信是通过这个新的套接字上发送和接收数据来完成的。
client_socket,address=server.accept()#address是自动分配的接口
recv_data=client_socket.recv(1024)#利用专门负责客户端通信的socket进行,此时负责监听的socket套接字可以关闭
client_socket.send("hello")
client_socket.close()
sever.close()#如果需要的化
注意对于服务端端口是自己设定的,对于客户端的端口是系统分配的
多人聊天的方式:
sever端打开监听socket,
server端接收到一个客户端,建立一个socket与客户端建立起单独的联系,建立一个线程专门负责该客户端
相比于TCP socket这个方法有以下不同:
不许建立连接
无需任何准备就可以进行数据传输
头部开销小
但是连接不可靠
UnboundLocalError: local variable ‘args’ referenced before assignment:变量未被正确引用,找不到,未赋值
1、学习pyechart orz
2、系统完整的学习装饰器的各类用法
3、ffmpeg配不好
4、os路径走法
5、虚拟子类