当前位置:   article > 正文

PYTHON笔记_socket plotter和 simple socket有什么区别

socket plotter和 simple socket有什么区别

PYTHON笔记

一些概念

NLP自然语言处理自然语言处理(NLP)就是在机器语言和人类语言之间沟通的桥梁,以实现人机交流的目的。人类通过语言来交流,狗通过汪汪叫来交流。机器也有自己的交流方式,那就是数字信息。

BERT预训练模型:

Word2vec

基本语法

声明

py文件开头声明解码方式
#-*- coding: utf-8 -*
  • 1

文件读写

在文件读写中只有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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

文件写入的方式:

[(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.读取数据)


文件csv读写方法

csdn:Python读取csv文件的几种方法_domoNaruto的博客-CSDN博客_python 读取csv

利用csv库&open
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
利用numpy库
import numpy as np
data = np.loadtxt(open("路径.csv","rb"),delimiter=",",skiprows=n,usecols=[2,3]) 
  • 1
  • 2
利用pandas
import pandas as pd
f=pd.read_csv("D:\\经管大三\\现代程序设计\\week4\\twitch_gamers\\large_twitch_features.csv","r",encoding="utf-8")
print(type(f))##输出格式为数据框
  • 1
  • 2
  • 3

打印print

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")
#两者的输出结果相等
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
检查print结果

(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"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

进阶语法

数据处理

利用映射map函数
string_date='2016-8-1'
year,month,day=map(int,string_date.split('-'))
s=Data_test(year,month,day)
  • 1
  • 2
  • 3
处理空值
计算相关性

(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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

序列化与反序列化

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)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

当出现raise时,会直接出发except报错,从而跳过return,并不会返回return值

try:
	dddd
except <error1>:
    ddddd
except <error2>:
    dddd
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
自定义异常&抛出异常&捕获异常

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())

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
清理行为

通过finally子句实现,定义无论在任何情况下都会执行的清理行为。无论try子句有无发生异常,finally子句都会执行,即使try执行了return

python的try finally (还真不简单) - 永远的幻想 - 博客园 (cnblogs.com)

with…as自动清理

with open as调用结束自动清理空间

warnings
try: except: continue

(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)()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
装饰器类
装饰器常用方法
functools

(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
'''
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
property实例属性化

将类中的函数变成属性直接调用,可以获取私有属性

(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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

@方法名.setter

修改属性值 ,实现属性的读写

@area.setter

@方法名.setter
def 方法名(self, value):
    代码块
  • 1
  • 2
  • 3
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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

@方法名.deleter

删除属性

@area.deleter

classmethod类方法

python @classmethod 的使用场合 - 知乎 (zhihu.com)

staticmethod静态方法(用的不多)

Python进阶-----静态方法(@staticmethod) - Meanwey - 博客园 (cnblogs.com)

@wraps

使得在使用修饰器时返回的仍然是调用的函数名,而不是内嵌函数

(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,这时候就可以正常打印被装饰函数的名字、注释等方法了。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

通用格式 用于修饰名字,注意传入函数参数,所以外面还有一个函数def dec(fun):…return wrapper

		@wraps(func)
		def wrapper(*args,**kwargs):
			print(text+' '+'call '+func.__name__)
			return func(*args,**kwargs)
		return wrapper
  • 1
  • 2
  • 3
  • 4
  • 5
@profile代码内存占用分析

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EFY3XQLy-1678455709917)(C:\Users\kerrla\AppData\Roaming\Typora\typora-user-images\image-20221023161118520.png)]

@proflie代码执行时长分析

(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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

上面的代码需要通过命令行运行

kernprof -lv ld.py##ld.py为文件名
  • 1

下面的代码在程序中执行

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()#打印状态结果
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
闭包

返回函数不宜引用任何循环变量,或者后续会发生变化的变量

python中闭包详解 - 知乎 (zhihu.com)

添加进度条

tqdm

(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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

pysnooper测试代码运行时间

观察者模式、生成器、迭代器

观察者模式

也被称作发布(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
  • 1
  • 2
  • 3
  • 4
  • 5
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()	
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
@abstractmethod方法,将类抽象化

(6条消息) Python @abstractmethod 抽象方法_jiang_huixin的博客-CSDN博客_python abstractmethod

Python 抽象类 (zditect.com)

生成器

Python生成器详解 (biancheng.net)

yield

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后的数值
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
获取返回值需要捕获stopIteration异常

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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
next()

Python next() 函数 | 菜鸟教程 (runoob.com)

迭代器:Iterable

可以被next()函数调用并不断返回下一个值的对象称为迭代器

##判断一个对象是否可以被迭代
from collections import Iterable
isinstance([1,2,3],Iterable)
  • 1
  • 2
  • 3
iter()
创建迭代器 基于类

把一个类作为一个迭代器使用需要在类中实现两个方法 __ iter __ () 与 __ next __()

__ iter __ ()返回一个特殊的迭代器对象,这个迭代器对象实现了 __ next __()方法

__ next __ () 方法返回下一个元素并通过StopIteration 异常标识迭代完成

迭代器相关工具itertools、内置函数

抽象类&元类

什么是抽象类? - 知乎 (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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

抽象类借助abc模块实现

(11条消息) 31.Python中的抽象类 (Abstract Class)_bai666ai的博客-CSDN博客_python抽象类

class Plotter(abc.ABC):#构造抽象类Plotter
    @abc.abstractmethod
    def plot(self,*args,**kwargs):
        pass
  • 1
  • 2
  • 3
  • 4

注册抽象类

@Abstract.register

虚拟子类

对于用户自定义的类型,即使不注册,抽象基类也能把一个是类别识别为虚拟子类

  • siinstance
  • issubclass

进程&线程

(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('结束测试')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
multiprocessing模块

开启子进程并在其中执行定制任务;提供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是可选的超时时间

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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也就跟着结束掉了
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
进程的同步

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

joinablequeue(maxsize)

python 并发编程 多进程 JoinableQueue - minger_lcm - 博客园 (cnblogs.com)


  • 1
管道

(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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
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('所有消息接收完成...')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
内存共享

以下的方法都需要加锁,只是开辟了一个共享内存空间,将数据映射到该空间上共进程处理

加锁有两种方法

from multiprocessing import Lock
lock=Lock()
lock.require()
block
lock.release()

------------
with lock:
    block
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

–内存共享通过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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

–通过manager实现内存共享

manger返回的管理器对象控制一个服务进程,且由该进程保护python对象并允许其他进程通过代理操作对象。

返回的管理器支持类型支持value、Array、dict、list、Lock、Semaphore等等,同时Manager还可以共享类的实例对象。

manager=Manager()
dic=manager.dict()
  • 1
  • 2
进程池

–进程开启过多导致效率下降(同步,切换成本,减少进程创建和销毁的过程)

–应固定工作进程的数目

  • 由这些进程执行所有任务,而非开启更多的进程
  • 与CPU核数有关

Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。

创建进程池

  • Pool
form multiprocessing import Pool
Pool(numprocess,initializer,initargs)
--numprocess 要创建的进程数,默认使用os.cpu_count()的值
--initializer 每个工作进程启动时要执行的可调用对象,默认为None
--initargs 可调用对象的参数

p=Pool()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

p.apply()

同步调用;只有一个进程执行(不并行);但可以直接得到返回结果(阻塞至返回结果)

apply(func, args=(), kwds={})
  • 1

p.apply_async()

异步调用;并行执行,结果不一定马上返回;可以有回调函数:进程池中任意进程完成任务后会立即通知主进程,主进程将调用另一个函数去处理该结果,该函数即回调函数,其参数为返回结果

python在同一个线程中多次执行同一方法时,该方法执行耗时较长且每次执行过程及结果互不影响,如果只在主进程中执行,效率会很低,因此使用multiprocessing.Pool(processes=n)及其apply_async()方法提高程序执行的并行度从而提高程序的执行效率,其中processes=n为程序并行执行的进程数。

p.close()

关闭进程池

p.join()

等待所有工作进程退出,只能在close()或teminate()之后调用

补充:

回调函数的参数只有一个,即结果
回调参数由主进程调用
回调函数应该迅速结束
回调的顺序根子进程启动顺序无关
-p.map() 并行,主进程会等待所有子进程结束
-p.map_async() 并行,有回调函数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

函数回调

进程池、线程池、回调函数 - 腾讯云开发者社区-腾讯云 (tencent.com)

可以在完成了函数以后直接回调,也可以在全部执行完统一执行

  • ProcessPoolExecutor
-对multiprocessing进一步抽象
-提供更简单、统一的接口

  • 1
  • 2
  • 3
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()
        
        
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
ProcessingPoolExecutor()生成一个进程池,然后直接将各参数依次传入,自动分配进程
submit()提交一个特定任务,返回一个实例--返回的实例结果需要用res.result(),如果马上调用这个结果会使得进程阻塞
map()批量提交函数,返回可迭代的结果对象
shutdown()关闭进程池
建议使用with,退出时自动调用shutdown()释放资源。
  • 1
  • 2
  • 3
  • 4
  • 5

(14条消息) 【极客日常】python进程池ProcessPoolExecutor的用法与实现分析_utmhikari的博客-CSDN博客

(14条消息) Python ProcessPoolExecutor实践_Kevin9436的博客-CSDN博客_processpoolexecutor

分布式多进程

–多机环境

–跨设备数据交流

–如master-worker模型

–通过manager暴露queue

多线程
  • python多线程的全局锁

GIL(global inerpreter lock)

GIL非python特性,而是实现python解释器(cpython)时引入的概念

–GIL本质上是一个互斥锁

–GIL在解释器级保护共享数据

  • 多线程vs多进程

进程可以利用多核,但是开销大,而多线程开销小,但却无法利用多核

多进程从内存的角度看,线程是分配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')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

线程同步:

···锁:

可重入锁,一旦线程获得了可重入锁,再次获取时将不阻塞

线程必须在每次获取后释放一次

区别在于:线程可以利用可重入锁,进行任务的递归调用

···信号量:

···事件:

···条件:当满足条件的时候,通知,很像观察者模式

python笔记11-多线程之Condition(条件变量) - 上海-悠悠 - 博客园 (cnblogs.com)

···定时器

···Barrier(栅栏):

某一特定位置,彼此等待,等待都到这一个位置后,再次并发执行

wait()方法来实现线程间的等待

  • 线程局部变量

–通过threading.loacl()创建

–线程在使用该类变量时会创建独立变量的拷贝

  • 队列

···queue.Queue

···queue.LifoQueue

···queue.PriorityQueue

  • 多线池

python线程池 ThreadPoolExecutor 的用法及实战 - 简书 (jianshu.com)

  • 信号
  • 守护线程

内置函数

isinstance(a,type)类型判断

max

#key表示返回最大值的方法,如key=dict.get,返回键
max(iterable, *[, key, default])
max(arg1, arg2, *args[, key])
  • 1
  • 2
  • 3

sorted函数

filter()过滤序列

Python3 filter() 函数 | 菜鸟教程 (runoob.com)

对象类型

列表

zip合并多个列表

tuple与list互化

Python zip() 函数 | 菜鸟教程 (runoob.com)

字典

菜鸟教程:Python3 字典 | 菜鸟教程 (runoob.com)

dict和tuple相互转换
>>> 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}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

可以利用zip函数,使列表被打包,用来生成两列表的对应关系,其次对于zip的打印,需要转化为list。对于索引的调用,需要记住python索引不包括最后一位。

dict.get()
dic={}
dic[key]=dic.get(key,0)+1
  • 1
  • 2

用于生成一个字典,并且统计词频时使用,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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

对键值大小排序

(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("在模块外调用")
  • 1
  • 2
  • 3
  • 4
  • 5

模块仅被导入一次,多次调用模块也只出现一次“在模块外调用”

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()
  • 1
  • 2

使用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}
'''
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

菜鸟教程: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)#这一步会报错,因为该属性被改变,使得找不到路径
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

类有私有属性,在前面加一个__双下划线,私有属性只能在类内使用,不能在类外随意调用,貌似类外调用类内属性会被伪装。

*xx: 公有变量
_x: 单前置下划线,私有化属性或方法,from somemodule import 禁止导入,类对象和子类可以访问
_xx:双前置下划线,避免与子类中的属性命名冲突,无法在外部直接访问(名字重整所以访问不到)
xx:双前后下划线,用户名字空间的魔法对象或属性。例如:init , __ 不要自己发明这样的名字
xx:单后置下划线,用于避免与Python关键词的冲突
通过name mangling(名字重整(目的就是以防子类意外重写基类的方法或者属性)如:_Class__object)机制就可以访问private了。

__ dict __ :

类的数据属性,默认情况下通过字典__ 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}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
__ slot __:
__ new __:

Python new()方法详解 (biancheng.net)

new() 是一种负责创建类实例的静态方法,它无需使用 staticmethod 装饰器修饰,且该方法会优先 init() 初始化方法被调用。

__ call __:

将实例变为可调用对象

(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)()       其中表示将实例变为可调用的函数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
__ subclassshook __()虚拟子类的专有方法
私有属性和私有方法

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()   #方法名同,默认调用的是在括号中参数位置排前父类的方法

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

派生类可能会覆盖其基类的方法

super()多继承顺序

(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__
# (<class '__main__.C'>, <class '__main__.A'>,
#  <class '__main__.X'>, <class '__main__.B'>, 
# <class '__main__.Y'>, <type 'object'>)
##查找顺序
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

(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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
object类

(3条消息) Python - Object类_星小白的博客-CSDN博客_python类object

所有类的父类,默认所有的类都继承至object父类,如果有父类才编写,如果没有父类可以省略

运算符重载

(3条消息) python之运算符重载_zsj.python之路的博客-CSDN博客_python重载运算符

(3条消息) 浅析Python运算符重载_viclee108的博客-CSDN博客_python 重载比较运算符

工厂模式

工厂模式依然是一种创建型设计模式,作为工厂,它所关心的是产品的产生,也就是对象的创建,我们利用工厂来创建对象,而不必我们亲自创建对象,我们无需去理解如何创建对象,只需要向工厂提出要求,让工厂去根据你的要求,给你生产你要的产品,给你相应的对象,这种模式便叫做工厂模式。

Python实现设计模式——工厂模式 - 骑鱼嘚猫 - 博客园 (cnblogs.com)

类的自定义 __ iter __ , __ next __ 为可迭代对象

(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(
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

iter 和 next 方法是python中约定好的,定义以上两种函数就表示这是一个可迭代的类

1)通过在类中添加 __iter__函数,向系统说明这是一个可迭代对象。

2)通过在类中添加 __next__函数,向系统提供该可迭代对象的迭代算法

3)在代码执行过程中,for循环函数会自动检查系统信息,识别__iter__函数,然后自动调用对应的__next__函数,生成一个迭代器。

4)所以在定义一个可迭代类时,一般__iter__ 函数要与 __next__函数成对出现。__iter__函数向系统声明这个类可迭代,__next__定义了具体的迭代器。

5)iter 与 __next__两个函数名不可改变,否则系统会不识别。

6)__next__函数的 return 在 if 判别命令的内部,每次执行__next__函数时,单次判别后直接输出。不满足判别条件时输出迭代终止。

dataframe数据框操作

(5条消息) Python Pandas中dataframe常用操作(创建、读取写入、切片等)_Parzival_的博客-CSDN博客_python 写入dataframe

数据框缺失值填充

(5条消息) python做数据分析时缺失值填补、缺失值填充方法汇总_theskylife的博客-CSDN博客_python对某一列填充某个值

数据框缺失值位置

(5条消息) Python Pandas找到缺失值的位置_kevinorg123的博客-CSDN博客_pandas查找缺失值

pandas和numpy联合使用:numpy使用的是np.where返回标签序号

各种包和模块。

math库

collections库

tkinter库

this库

wordcloud库&jieba库

生成词云的方法

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')

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

pandas库

空值填充

(5条消息) python做数据分析时缺失值填补、缺失值填充方法汇总_theskylife的博客-CSDN博客_python对某一列填充某个值

numpy库

csv库:内置

(5条消息) python中csv文件的创建、读取、修改等操作总结_m0_46483236的博客-CSDN博客_python读csv文件并修改

PIL库(pillow)

Pillow - 教程 - 蝴蝶教程 (jc2182.com)

深度学习之gensim库

时间处理之datetime库

Python常用标准库之datetime模块 - 知乎 (zhihu.com)

社会网络分析与挖掘之networkx库

官网教程及例子:教程 — 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
  • 1

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()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

create edge

G.add_edge(2,"A")#连接节点2和A
G.add_edges_from([(1,2),(1,3),(2,"A"),(2,3)])#添加多条边
  • 1
  • 2

为节点添加属性

sf
  • 1

可视化:用networkx做网络关系可视化 - 简书 (jianshu.com)

networkx 画图布局_ACxz的博客-CSDN博客_networkx画图

**关于图的一些知识:**

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/621393
推荐阅读
相关标签