• [热门活动] Python编程创造营“如果”和“复读机”小结实验任务(2)
    任务:计算猴子吃桃问题。猴子第 1 天摘了若干个桃子,当即吃了一半零一个;第 2 剩下的吃了一半零一个,一次循环。到第十天时想吃就剩下一个桃子。求第一天摘了几个桃子?本小白的代码是:j = 1for i in range(1,10):    j = (j+1)*2print(j)输出结果为:1534 本小白的思路是:属于数学的递归问题,在高中一个用数列的方式解决(也许)。但是,在Python中,可以利用for in range进行循环。D9=X/2-1=D10,因此推导出,D9=2*(D10+1),即f{x+1}=2[f(x)+1]所以,j = (j+1)*2。写在最后,作者本科商科,从未碰过代码。因,研究生专业为区块链技术,不得已开始自学编程。以上帖子仅为作者对该任务的一些粗浅认识,如果其中文字或者代码有误,希望各位大神/大佬/前辈不吝赐教,谢谢!!!
  • [热门活动] Python编程创造营“如果”和“复读机”小结实验任务(1)
    任务:当前有一组成绩单: score = [100,79,65,87,97,65,87,97,67] 请去除成绩单中成绩大于 80 的成绩,并将取出后的列表打印出来 本小白的代码是:score = [100,79,65,87,97,65,87,97,67]for i in score:    if i > 80:        continue    print(i,end=" ")输出结果为:79 65 65 67  本小白的思路是:首先,确定给定数据——列表,因此可以直接使用,如果是其他的话需要转换。eg.score = 100,79,65,87,97,65,87,97,67score_list=list(score)接着,取出小于80的值。在这里的思路为,利用for和if函数遍历列表的数字,并在数值大于80时continue(跳过)。利用for和if函数遍历列表中的数字:score = [100,79,65,87,97,65,87,97,67]for i in score:#遍历数字    if i > 80:        continue#当列表中的数字大于80时跳过    print(i,end=" ")#打印数字,并使用end让数字间空格为1.更多的思考在部分操作中,可能还需要将学生成绩排序。因此,可以在代码中增加相关语句以实现该目的。将获得列表中的数值从大到小排序:raw_score = score.copy() # copy 方法实现浅拷贝raw_score.sort(reverse=True)※Python对部分字符大小写有要求,不用把True写成true。※※排序后原数据会被更改,因此在此操作前一定要copy!!全部代码为:score = [100,79,65,87,97,65,87,97,67]for i in score:    if i > 80:        continue    print(i,end=" ")print()sort_score = score.copy() sort_score.sort(reverse=True)for i in sort_score:    if i > 80:        continue    print(i,end=" ")print()print(score)print(sort_score)输出结果为:79 65 65 67 #未排序,符合小于8079 67 65 65 #排序,符合小于80[100, 79, 65, 87, 97, 65, 87, 97, 67]#未排序,原数据[100, 97, 97, 87, 87, 79, 67, 65, 65]#排序,从大到小数据写在最后,作者本科商科,从未碰过代码。因,研究生专业为区块链技术,不得已开始自学编程。以上帖子仅为作者对该任务的一些粗浅认识,如果其中文字或者代码有误,希望各位大神/大佬/前辈不吝赐教,谢谢!!!
  • [问题求助] 【MindElec的GPU编译版本】【MindElec源码编译过程中出现问题】Could NOT find Python3
    【功能模块】电磁计算平台MindElec【操作步骤&问题现象】需求:在RTX3060 Gpu上运行mindelec电磁计算平台,由于官方只支持ascend,只能用源码编译的方式1、在wsl中完成minds pore1.7-gpu版本的安装及测试后,尝试在Ubuntu-20.04的wsl中利用源码编译的方式安装mindelec敲出命令 bash build.sh -e gpu 出现报错-- Could NOT find Python3 (missing: Python3_INCLUDE_DIRS Development) (found version "3.8.10")CMake Error at CMakeLists.txt:35 (find_python_package):  Unknown CMake command "find_python_package".-- Configuring incomplete, errors occurred!See also "/home/lihongji/mindscience/MindElec/build/mindelec/CMakeFiles/CMakeOutput.log".2、详细操作信息:(base) lihongji@LAPTOP-P7NAUT00:~/mindscience/MindElec$ bash build.sh -e gpumkdir: created directory '/home/lihongji/mindscience/MindElec/output'---------------- MindElec: build start ----------------start build mindelec project.-DDEBUG_MODE=off -DBUILD_PATH=/home/lihongji/mindscience/MindElec/build/ -DENABLE_GPU=ONMD LIBS CACHE PATH:  /home/lihongji/mindscience/MindElec/build/mindelec/.mdlibset make thread num: 8pkg name:pybind11,pybind11pybind11 config hash: 5253018179879c380bb2d33c476f2438-- Found pybind11: /home/lihongji/mindscience/MindElec/build/mindelec/.mdlib/pybind11_5253018179879c380bb2d33c476f2438/include (found version "2.6.1" )Found pkg: pybind11pkg name:glog,glogglog config hash: 6f581a3db68ffe9e125bd4c496da9aaa_FIND:/home/lihongji/mindscience/MindElec/build/mindelec/.mdlib/glog_6f581a3db68ffe9e125bd4c496da9aaafound /home/lihongji/mindscience/MindElec/build/mindelec/.mdlib/glog_6f581a3db68ffe9e125bd4c496da9aaa/lib/libglog.soFound libs: glog::glogpkg name:nlohmann_json,nlohmann_jsonnlohmann_json config hash: e0a3765b49b7f4747a26bc3db79d0028========== External libs built successfully ==========-- Could NOT find Python3 (missing: Python3_INCLUDE_DIRS Development) (found version "3.8.10")CMake Error at CMakeLists.txt:35 (find_python_package):  Unknown CMake command "find_python_package".-- Configuring incomplete, errors occurred!See also "/home/lihongji/mindscience/MindElec/build/mindelec/CMakeFiles/CMakeOutput.log".之前已经完成过一部分的编译,重新编译只显示该部分信息【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [其他] vscode安装远端插件时不稳定,需尝试多次解决办法
    方法一:离线包安装方式(推荐)到VS Code插件官网vscode_marketplace搜索待安装的Python插件,Python插件路径。单击进入Python插件的Version History页签后,下载该插件的离线安装包,如图所示。图1 Python插件离线安装包在本地VS Code环境中,将下载好的.vsix文件拖动到远端Notebook中。右键点击该文件,选择Install Extension VSIX。方法二:设置远端默认安装的插件按照VS Code中设置远端默认安装的插件配置,即会在连接远端时自动安装,减少等待时间。方法三:VS Code官网排查方式https://code.visualstudio.com/docs/remote/troubleshooting小技巧(按需调整远端连接的相关参数): "remote.SSH.connectTimeout": 10, "remote.SSH.maxReconnectionAttempts": null, "remote.downloadExtensionsLocally": true, "remote.SSH.useLocalServer": false, "remote.SSH.localServerDownload": "always",
  • [其他] 在VS Code中远程调试代码
    前提条件VS Code已连接到Notebook。Step1上传本地代码到云端开发环境。在VS Code界面,单击“File > OpenFolder”打开云端路径。图1 Open Folder选择要打开的路径,单击“OK”。图2 选择文件路径此时,会在IDE左侧出现该开发环境下的目录结构,把想要上传的代码及其他文件直接拖拽至对应的文件夹内即完成本地代码上传至云端。Step2 远程调试代码。在VS Code中打开要执行的代码文件,在执行代码之前需要选择合适的Python版本路径,单击下方默认的Python版本路径,此时在上方会出现该远程环境上所有的python版本,选择自己需要的版本即可。图3 选择Python版本对于打开的代码文件,单击run按钮,即可执行,可以在下方的Terminal中看到代码输出信息。如果执行较长时间的训练任务,建议使用nohup命令后台运行,否则SSH窗口关闭或者网络断连会影响正在运行的训练任务,命令参考:nohup your_train_job.sh > output.log 2>&1 & tail -f output.log如果要对代码进行debug调试,步骤如下:单击左侧“Run > Run and Debug”。选择当前打开的默认的python代码文件进行调试。对当前代码进行打断点,即在代码左侧进行单击,就会出现小红点。此时,即可按照正常的代码调试步骤对代码调试,在界面左边会显示debug信息,代码上方有相应的调试步骤。
  • [知识分享] Python图像处理丨三种实现图像形态学转化运算模式
    【摘要】 该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。本篇文章主要讲解Python调用OpenCV实现图像形态学转化,包括图像开运算、图像闭运算和梯度运算,基础性知识希望对您有所帮助。本文分享自华为云社区《[Python图像处理] 九.形态学之图像开运算、闭运算、梯度运算》,作者:eastmount。该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。希望文章对您有所帮助,如果有不足之处,还请海涵~数学形态学(Mathematical morphology)是一门建立在格论和拓扑学基础之上的图像分析学科,是数学形态学图像处理的基本理论。其基本的运算包括:腐蚀和膨胀、开运算和闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat变换、颗粒分析、流域变换等。本篇文章主要讲解Python调用OpenCV实现图像形态学转化,包括图像开运算、图像闭运算和梯度运算,基础性知识希望对您有所帮助。1.图像开运算2.图像闭运算3.图像梯度运算一. 图像开运算1.基本原理图像开运算是图像依次经过腐蚀、膨胀处理后的过程。图像被腐蚀后,去除了噪声,但是也压缩了图像;接着对腐蚀过的图像进行膨胀处理,可以去除噪声,并保留原有图像。如下图所示:开运算(img) = 膨胀( 腐蚀(img) ) 下图是hanshanbuleng博主提供的开运算效果图,推荐大家学习他的文章。https://blog.csdn.net/hanshanbuleng/article/details/806571482.函数原型图像开运算主要使用的函数morphologyEx,它是形态学扩展的一组函数,其参数cv2.MORPH_OPEN对应开运算。其原型如下:dst = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)参数dst表示处理的结果,src表示原图像,cv2.MORPH_OPEN表示开运算,kernel表示卷积核。下图表示5*5的卷积核,可以采用函数 np.ones((5,5), np.uint8) 构建。运行结果如下图所示:3.代码实现完整代码如下所示:#encoding:utf-8 import cv2 import numpy as np #读取图片 src = cv2.imread('test01.png', cv2.IMREAD_UNCHANGED) #设置卷积核 kernel = np.ones((5,5), np.uint8) #图像开运算 result = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel) #显示图像 cv2.imshow("src", src) cv2.imshow("result", result) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()输出结果如下图所示,可以看到噪声已经被去除了。但是结果result中仍然有部分噪声,如果想去除更彻底将卷积设置为10*10的。kernel = np.ones((10,10), np.uint8)result = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)二. 图像闭运算1.基本原理图像闭运算是图像依次经过膨胀、腐蚀处理后的过程。图像先膨胀,后腐蚀,它有助于关闭前景物体内部的小孔,或物体上的小黑点。如下图所示:闭运算(img) = 腐蚀( 膨胀(img) )  下图是hanshanbuleng博主提供的开运算效果图,推荐大家学习他的文章。2.函数原型图像闭运算主要使用的函数morphologyEx,其原型如下:dst = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)参数dst表示处理的结果,src表示原图像, cv2.MORPH_CLOSE表示闭运算,kernel表示卷积核。下图表示5*5的卷积核,可以采用函数 np.ones((5,5), np.uint8) 构建。运行结果如下图所示:3.代码实现完整代码如下所示:#encoding:utf-8 import cv2 import numpy as np #读取图片 src = cv2.imread('test03.png', cv2.IMREAD_UNCHANGED) #设置卷积核 kernel = np.ones((10,10), np.uint8) #图像闭运算 result = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel) #显示图像 cv2.imshow("src", src) cv2.imshow("result", result) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()输出结果如下图所示,可以看到中间的噪声去掉。三. 图像梯度运算1.基本原理图像梯度运算是膨胀图像减去腐蚀图像的结果,得到图像的轮廓,其中二值图像1表示白色点,0表示黑色点。如下图所示:梯度运算(img) = 膨胀(img) - 腐蚀(img) 2.函数原型图像梯度运算主要使用的函数morphologyEx,参数为cv2.MORPH_GRADIENT。其原型如下:dst = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel)参数dst表示处理的结果,src表示原图像, cv2.MORPH_GRADIENT表示梯度运算,kernel表示卷积核。5*5的卷积核可以采用函数 np.ones((5,5), np.uint8) 构建。运行结果如下图所示:3.代码实现完整代码如下所示:#encoding:utf-8 import cv2 import numpy as np #读取图片 src = cv2.imread('test04.png', cv2.IMREAD_UNCHANGED) #设置卷积核 kernel = np.ones((10,10), np.uint8) #图像闭运算 result = cv2.morphologyEx(src, cv2.MORPH_GRADIENT, kernel) #显示图像 cv2.imshow("src", src) cv2.imshow("result", result) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows() 输出结果如下图所示,可以看到中间的噪声去掉。
  • [技术干货] 【ManasAI-OCR】验证码、健康码颜色识别、表格图片识别
    前言:使用了Manas提供的AI能力进行拓展插件二次开发。需要申请权限,才能正常使用注意:1. 以下控件中,需要提供用户账号。用户账号为在WeAutomate_AI申请的账号。如果没有注册,或者该账号没有激活,会报以下错误[Detail] [NOK] [2022-07-19 16:19:35]完成执行[原子命令] [playbackScript.xml 第4行] 验证码、健康码识别 [验证码、健康码识别] [NOK] [RobotUncaughtError] [系统执行错误: 发生了未捕获异常,详情:RuntimeError('Your account is not a member of tenant WeAutomate_AI, or your account is inactive.')]账号申请相关操作,请参考:https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=1947342. 插件使用了python库:xlwt,需要自行安装如果运行出现“no module named 'xlwt'”,则进入黑窗口cmd,设计器是stduio/python/文件夹下(执行器是assistant/python/)执行 python.exe -m pip install xlwt;若黑窗口cmd中,出现Retry等字样信息,则需要将pip.rar(见附件)中的pip文件放入'C:\Users\用户名' 文件夹下,即自己的用户账号下(例如'C:\Users\工号','C:\Users\Administrator', 'C:\Users\Lenovo'等等)。功能说明提供了验证码识别、健康码颜色识别、表格图片识别功能导入1. 从studio中导入附件ext_ManasOCRVerify_2_0_0.zip2. 成功后,会在扩展中心中看到我们导入的包3. 控件中会出现以下新增控件验证码识别、健康码颜色识别1. 控件帮忙界面见下图2. 属性界面下二图。(识别模式有三种,健康码识别、验证码识别;验证码识别中,需要选择是纯数字,还是纯字母,还是数字与字母混合)表格图片识别功能说明:使用AI-OCR识别,将表格图片内容识别出来,也能够转为对应的Excel文件入参说明:如果不在本地生成Excel文件,可以忽略“很长Excel文件的路径”和“工作表sheet”执行结果:在指定的路径生成Excel文件,其中list类型的返回值table_ret,如图
  • [技术干货] 哈夫曼树的实现-python
     哈夫曼树的实现与应用一、实验目的掌握哈夫曼树的存储结构和应用。熟练掌握哈夫曼树构造哈夫曼编码。二、实验环境硬件:每个学生需配备计算机一台。操作系统:Windows;软件:Windows操作系统+pycharm; 三、实验要求及实验内容假设通信电文为“AAGGDCCCDDDGFBBBFFGGDDDDGGGEFFDDCCCCDDFGAAA”,编程实现对上述电文的哈夫曼编码。具体内容包括:编程实现电文中各个字符出现的频度,并输出。在1基础上,编程实现哈夫曼树的建立,哈夫曼树中内部节点用字符m代替,建好树后,输出先序遍历序列。在2基础上,编程实现哈夫曼编码和电文的编码,并输出每个字符对应的编码和整个电文的编码。在3基础上,编程实现电文的解码,输出电文序列并判定是否解码正确。 参考代码:(仅供参考)# 树节点类构建class TreeNode(object):    def __init__(self, data):        self.val = data[0]        #节点的值        self.priority = data[1]       #节点的优先度        self.leftChild = None     #节点的左子结点        self.rightChild = None   #节点的右子结点        self.code = ""            #节点值的编码# 创建树节点队列函数def creatnodeQ(codes):    q = []    for code in codes:        q.append(TreeNode(code))    return q# 为队列添加节点元素,并保证优先度从大到小排列def addQ(queue, nodeNew):    if len(queue) == 0:        return [nodeNew]    for i in range(len(queue)):        if queue[i].priority >= nodeNew.priority:            return queue[:i] + [nodeNew] + queue[i:]    return queue + [nodeNew]# 节点队列类定义class nodeQeuen(object):    def __init__(self, code):        self.que = creatnodeQ(code)        self.size = len(self.que)    def addNode(self,node):           #添加节点函数        self.que = addQ(self.que, node)        self.size += 1    def popNode(self):        #弹出节点函数        self.size -= 1        return self.que.pop(0)# 各个字符在字符串中出现的次数,即计算优先度def freChar(string):d ={}#定义一个字典,遍历文本中的每一个字母,若字母不在字典里说明是第一次出现,则定义该字母为键,另键值为1,若在字典里有,则只需将相应的键值加一。 遍历后就得到了每个字母出现的次数。    for c in string:        if not c in d:            d[c] = 1        else:            d[c] += 1    return sorted(d.items(),key=lambda x:x[1])# 创建哈夫曼树def creatHuffmanTree(nodeQ):    while nodeQ.size != 1:        node1 = nodeQ.popNode()        node2 = nodeQ.popNode()        r = TreeNode([None, node1.priority+node2.priority])        r.leftChild = node1        r.rightChild = node2        nodeQ.addNode(r)    return nodeQ.popNode()codeDic1 = {}        #用于编码codeDic2 = {}         #用于解码# 由哈夫曼树得到哈夫曼编码表def HuffmanCodeDic(head, x):    global codeDic, codeList    if head:        HuffmanCodeDic(head.leftChild, x+'0')     # 二叉树的中序遍历,每递归到深一层的时候,就在后面多加一个‘0’(左子树)或‘1’(右子树)。        head.code += x        if head.val:            codeDic2[head.code] = head.val            codeDic1[head.val] = head.code        HuffmanCodeDic(head.rightChild, x+'1')# 字符串编码def TransEncode(string):    global codeDic1    transcode = ""    for c in string:        transcode += codeDic1[c]    return transcode# 字符串解码def TransDecode(StringCode):    global codeDic2    code = ""    ans = ""    for ch in StringCode:        code += ch        if code in codeDic2:            ans += codeDic2[code]            code = ""    return ans
  • [知识分享] Python图像处理丨图像腐蚀与图像膨胀
    【摘要】 该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。本篇文章主要讲解Python调用OpenCV实现图像腐蚀和图像膨胀的算法,基础性知识希望对您有所帮助。本文分享自华为云社区《[Python图像处理] 八.图像腐蚀与图像膨胀》,作者: eastmount 。本篇文章主要讲解Python调用OpenCV实现图像腐蚀和图像膨胀的算法,基础性知识希望对您有所帮助。1.基础理论2.图像腐蚀代码实现3.图像膨胀代码实现一. 基础知识(注:该部分参考作者论文《一种改进的Sobel算子及区域择优的身份证智能识别方法》)图像的膨胀(Dilation)和腐蚀(Erosion)是两种基本的形态学运算,主要用来寻找图像中的极大区域和极小区域。其中膨胀类似于“领域扩张”,将图像中的高亮区域或白色部分进行扩张,其运行结果图比原图的高亮区域更大;腐蚀类似于“领域被蚕食”,将图像中的高亮区域或白色部分进行缩减细化,其运行结果图比原图的高亮区域更小。1.图像膨胀膨胀的运算符是“⊕”,其定义如下:该公式表示用B来对图像A进行膨胀处理,其中B是一个卷积模板或卷积核,其形状可以为正方形或圆形,通过模板B与图像A进行卷积计算,扫描图像中的每一个像素点,用模板元素与二值图像元素做“与”运算,如果都为0,那么目标像素点为0,否则为1。从而计算B覆盖区域的像素点最大值,并用该值替换参考点的像素值实现膨胀。下图是将左边的原始图像A膨胀处理为右边的效果图A⊕B。处理结果如下图所示:2.图像腐蚀腐蚀的运算符是“-”,其定义如下:该公式表示图像A用卷积模板B来进行腐蚀处理,通过模板B与图像A进行卷积计算,得出B覆盖区域的像素点最小值,并用这个最小值来替代参考点的像素值。如图所示,将左边的原始图像A腐蚀处理为右边的效果图A-B。处理结果如下图所示:二. 图像腐蚀代码实现1.基础理论形态学转换主要针对的是二值图像(0或1)。图像腐蚀类似于“领域被蚕食”,将图像中的高亮区域或白色部分进行缩减细化,其运行结果图比原图的高亮区域更小。其主要包括两个输入对象:(1)二值图像(2)卷积核卷积核是腐蚀中的关键数组,采用numpy库可以生成。卷积核的中心点逐个像素扫描原始图像,如下图所示:被扫描到的原始图像中的像素点,只有当卷积核对应的元素值均为1时,其值才为1,否则其值修改为0。换句话说,遍历到的黄色点位置,其周围全部是白色,保留白色,否则变为黑色,图像腐蚀变小。2.函数原型图像腐蚀主要使用的函数为erode,其原型如下:dst = cv2.erode(src, kernel, iterations)参数dst表示处理的结果,src表示原图像,kernel表示卷积核,iterations表示迭代次数。下图表示5*5的卷积核,可以采用函数 np.ones((5,5), np.uint8) 构建。注意:迭代次数默认是1,表示进行一次腐蚀,也可以根据需要进行多次迭代,进行多次腐蚀。3.代码实现完整代码如下所示:#encoding:utf-8 import cv2 import numpy as np #读取图片 src = cv2.imread('test01.jpg', cv2.IMREAD_UNCHANGED) #设置卷积核 kernel = np.ones((5,5), np.uint8) #图像腐蚀处理 erosion = cv2.erode(src, kernel) #显示图像 cv2.imshow("src", src) cv2.imshow("result", erosion) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()输出结果如下图所示:由图可见,干扰的细线被进行了清洗,但仍然有些轮廓,此时可设置迭代次数进行腐蚀。erosion = cv2.erode(src, kernel,iterations=9)输出结果如下图所示:三. 图像膨胀代码实现1.基础理论图像膨胀是腐蚀操作的逆操作,类似于“领域扩张”,将图像中的高亮区域或白色部分进行扩张,其运行结果图比原图的高亮区域更大,线条变粗了,主要用于去噪。(1) 图像被腐蚀后,去除了噪声,但是会压缩图像。(2) 对腐蚀过的图像,进行膨胀处理,可以去除噪声,并且保持原有形状。它也包括两个输入对象:(1)二值图像或原始图像(2)卷积核卷积核是腐蚀中的关键数组,采用numpy库可以生成。卷积核的中心点逐个像素扫描原始图像,如下图所示:被扫描到的原始图像中的像素点,当卷积核对应的元素值只要有一个为1时,其值就为1,否则为0。2.函数原型图像膨胀主要使用的函数为dilate,其原型如下:dst = cv2.dilate(src, kernel, iterations)参数dst表示处理的结果,src表示原图像,kernel表示卷积核,iterations表示迭代次数。下图表示5*5的卷积核,可以采用函数 np.ones((5,5), np.uint8) 构建。注意:迭代次数默认是1,表示进行一次膨胀,也可以根据需要进行多次迭代,进行多次膨胀。通常进行1次膨胀即可。3.代码实现完整代码如下所示:#encoding:utf-8 import cv2 import numpy as np #读取图片 src = cv2.imread('test02.png', cv2.IMREAD_UNCHANGED) #设置卷积核 kernel = np.ones((5,5), np.uint8) #图像膨胀处理 erosion = cv2.dilate(src, kernel) #显示图像 cv2.imshow("src", src) cv2.imshow("result", erosion) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()输出结果如下所示:图像去噪通常需要先腐蚀后膨胀,这又称为开运算,下篇文章将详细介绍。如下图所示:erosion = cv2.erode(src, kernel)result = cv2.dilate(erosion, kernel)
  • [问题求助] Python中无法用pip命令安装的三方包如何安装?
    【功能模块】Python【操作步骤&问题现象】1、需要安装三方库CheMPS2(https://github.com/SebWouters/CheMPS2)与DMET(https://github.com/SebWouters/QC-DMET)。CheMPS2是DMET的依赖库。2、由于没有打包,pip命令无法安装。在cloudIDE环境下怎样手动安装?【截图信息】
  • [技术干货] Snowflake Summit 2022重要技术看点
    UnistoreUnistore 的目标是消除公司处理的最常见的数据孤岛之一,即交易数据和分析数据。通常,公司将交易数据存储在针对交易进行了优化的传统数据库中。这些数据库具有基于行的表结构,专为快速插入和更新而设计。另一方面,数据仓库经过优化,可以存储和处理用于分析的数据。仓库中的底层表结构是基于列的,允许更高效地从存储中读取和写入数据——查询的快速返回。很简单,Unistore 使两种类型的数据都可以存储在同一个地方,每种类型都保持其固有的优势——使 Snowflake 用户能够对事务数据运行实时分析查询。Unistore 还为公司提供了利用其交易数据做更多事情的可能性,例如直接在仓库上构建交易业务应用程序。Snowpark for Python对于在现代数据堆栈的以 SQL 为中心的人来说,我们有时会暂时忘记 Python 的重要性。但是它可以说是世界上最流行的计算机语言,也是数据科学和机器学习的工具。Snowflake 一直在稳步与 Python 建立协同作用,包括去年宣布与 Python 创建者 Anaconda 建立合作伙伴关系以及推出 Python Dataframe API。在拉斯维加斯,Snowflake 宣布了“Snowpark for Python”,它为 Snowflake 的开发者平台带来了对 Python 的原生支持。目标是让数据科学家、机器学习工程师和开发人员更容易使用 Snowflake。这样,不仅能够利用 Python 语言,而且能够利用库、框架和工具的整个 Python 生态系统。Snowpipe streamingSnowflake分布了一种在 Snowflake 中提取数据的新方法:Snowpipe streaming。他们重构了Kafka 连接器,并使其在数据到达 Snowflake 时立即可查询,从而将延迟降低 10 倍。这将在今年晚些时候公开预览。Native AppsSnowflake 推出了“原生应用程序框架”,允许开发人员在他们的 Snowflake 实例中构建应用程序,而这些应用程序的最终消费者可以在他们的 Snowflake 实例中安装和运行它们。这个新框架的目标是节省将数据移动到应用程序所需的时间和精力。除此之外,在数据所在的位置运行应用程序可以提高运行时性能并创建高度安全的工作环境(这些应用程序也受益于 Snowflake 的安全和治理框架)。本机应用程序框架的另一个主要好处是货币化。开发人员可以通过在 Snowflake Marketplace 上发布他们的应用程序,直接向 Snowflake 的 6000 多家客户销售他们的应用程序。Marketplace 于 2020 年作为数据交换平台推出,允许 Snowflake 客户相互买卖数据集。但现在,它已经不仅仅是一个数据贩卖平台——许多评论员将其比作苹果和谷歌的应用商店。如果你和我一样,你会想知道——我们在这里谈论的是什么类型的应用程序?首先想到的是前面提到的 Streamlit 应用程序,以及基于事务数据的应用程序,这些应用程序现在可以通过 Unistore 实现。这两者绝对是 Snowflake 为原生应用程序框架所考虑的一部分。但是,目前,Snowflake 正在考虑这样一个事实,即 400 多名客户已经在仓库之上构建了自己的应用程序。迄今为止,最引人注目的例子之一是 Capital One 的“Slingshot”,它旨在简化 Snowflake 供应流程。随着时间的推移,Slingshot 演变成一种提供多种额外优势的解决方案,例如管理 Snowflake 成本和自动化数据治理。Capital One 认为它的应用程序非常好,值得出售给其他 Snowflake 用户,Snowflake 也同意。Slingshot 成为市场上首批可供购买的应用程序之一。Apache Iceberg支持Snowflake 的外部表将支持 Apache Iceberg[1]。Apache Iceberg 表是用于大型分析表的高性能格式,它为大数据带来了 SQL 表的可靠性和简单性,同时使 Apache Spark、Trino、Flink、Presto 和 Hive 等引擎能够同时安全地使用相同的表。参考资料[1] Apache Iceberg: https://iceberg.apache.org
  • [互动交流] 【RPA产品】【EXCEL抓取错误功能】用户电脑无法正确使用EXCEL插件功能
    【功能模块】 开发环境是 WIN 10, 开发的主要功能为 EXCEL 的文档从一个EXCEL 里面查找关键值后,COPY/PASTE 相关内容。 开发环境使用正常。 用户使用 Win11 的OS, 安装Assistant  以后, 日志里面无运行后无任何报错, 但是抓取的EXCEL 内容不正确, 控件执行不正常。 结果就是, 所有生成的的EXCEL 里面的内容都是一样的。 涉及到客户数据,无法截图。 请帮助。 对了, 我写了部分的 Python 程序,我放在项目的Lib 目录之内的。  些程序在发布后是放在什么地方的呢? 还是说,我发布的打包程序里面就有这些 Python程序? 版本就是Assistant的版本 是: 【操作步骤&问题现象】1、2、【截图信息】 【日志信息】(可选,上传日志内容或者附件)
  • [技术干货] Python面试基础篇 - 50道经典面试题(附答案及多种解答)[转载]
    题目001: 在Python中如何实现单例模式。点评:单例模式是指让一个类只能创建出唯一的实例,这个题目在面试中出现的频率极高,因为它考察的不仅仅是单例模式,更是对Python语言到底掌握到何种程度,建议大家用装饰器和元类这两种方式来实现单例模式,因为这两种方式的通用性最强,而且也可以顺便展示自己对装饰器和元类中两个关键知识点的理解。方法一: 使用装饰器实现单例模式。from functools import wrapsdef singleton(cls):    """单例类装饰器"""    instances = {}    @wraps(cls)    def wrapper(*args, **kwargs):        if cls not in instances:            instances[cls] = cls(*args, **kwargs)        return instances[cls]    return wrapper@singletonclass President:    pass扩展:装饰器是Python中非常有特色的语法,用一个函数去装饰另一个函数或类,为其添加额外的能力。通常通过装饰来实现的功能都属横切关注功能,也就是跟正常的业务逻辑没有必然联系,可以动态添加或移除的功能。装饰器可以为代码提供缓存、代理、上下文环境等服务,它是对设计模式中代理模式的践行。在写装饰器的时候,带装饰功能的函数(上面代码中的wrapper函数)通常都会用functools模块中的wraps再加以装饰,这个装饰器最重要的作用是给被装饰的类或函数动态添加一个__wrapped__属性,这个属性会将被装饰之前的类或函数保留下来,这样在我们不需要装饰功能的时候,可以通过它来取消装饰器,例如可以使用President = President.__wrapped__来取消对President类做的单例处理。需要提醒大家的是:上面的单例并不是线程安全的,如果要做到线程安全,需要对创建对象的代码进行加锁的处理。在Python中可以使用threading模块的RLock对象来提供锁,可以使用锁对象的acquire和release方法来实现加锁和解锁的操作。当然,更为简便的做法是使用锁对象的with上下文语法来进行隐式的加锁和解锁操作。方法二: 使用元类实现单例模式。class SingletonMeta(type):    """自定义单例元类"""    def __init__(cls, *args, **kwargs):        cls.__instance = None        super().__init__(*args, **kwargs)    def __call__(cls, *args, **kwargs):        if cls.__instance is None:            cls.__instance = super().__call__(*args, **kwargs)        return cls.__instanceclass President(metaclass=SingletonMeta):    pass扩展:Python是面向对象的编程语言,在面向对象的世界中,一切皆为对象。对象是通过类来创建的,而类本身也是对象,类这样的对象是通过元类来创建的。我们在定义类时,如果没有给一个类指定父类,那么默认的父类是object,如果没有给一个类指定元类,那么默认的元类是type。通过自定义的元类,我们可以改变一个类默认的行为,就如同上面的代码中,我们通过元类的__call__魔术方法,改变了President类的构造器那样。补充:关于单例模式,在面试中还有可能被问到它的应用场景。通常一个对象的状态是被其他对象共享的,就可以将其设计为单例,例如项目中使用的数据库连接池对象和配置对象通常都是单例,这样才能保证所有地方获取到的数据库连接和配置信息是完全一致的;而且由于对象只有唯一的实例,因此从根本上避免了重复创建对象造成的时间和空间上的开销,也避免了对资源的多重占用。再举个例子,项目中的日志操作通常也会使用单例模式,这是因为共享的日志文件一直处于打开状态,只能有一个实例去操作它,否则在写入日志的时候会产生混乱。题目002:不使用中间变量,交换两个变量a和b的值。点评:典型的送人头的题目,通常交换两个变量需要借助一个中间变量,如果不允许使用中间变量,在其他编程语言中可以使用异或运算的方式来实现交换两个变量的值,但是Python中有更为简单明了的做法。方法一:a = a ^ bb = a ^ ba = a ^ b方法二:a, b = b, a扩展:需要注意,a, b = b, a这种做法其实并不是元组解包,虽然很多人都这样认为。Python字节码指令中有ROT_TWO指令来支持这个操作,类似的还有ROT_THREE,对于3个以上的元素,如a, b, c, d = b, c, d, a,才会用到创建元组和元组解包。想知道你的代码对应的字节码指令,可以使用Python标准库中dis模块的dis函数来反汇编你的Python代码。题目003:写一个删除列表中重复元素的函数,要求去重后元素相对位置保持不变。点评:这个题目在初中级Python岗位面试的时候经常出现,题目源于《Python Cookbook》这本书第一章的第10个问题,有很多面试题其实都是这本书上的原题,所以建议大家有时间好好研读一下这本书。def dedup(items):    no_dup_items = []    seen = set()    for item in items:        if item not in seen:            no_dup_items.append(item)            seen.add(item)    return no_dup_items如果愿意也可以把上面的函数改造成一个生成器,代码如下所示。def dedup(items):    seen = set()    for item in items:        if item not in seen:            yield item            seen.add(item)扩展:由于Python中的集合底层使用哈希存储,所以集合的in和not in成员运算在性能上远远优于列表,所以上面的代码我们使用了集合来保存已经出现过的元素。集合中的元素必须是hashable对象,因此上面的代码在列表元素不是hashable对象时会失效,要解决这个问题可以给函数增加一个参数,该参数可以设计为返回哈希码或hashable对象的函数。题目004:假设你使用的是官方的CPython,说出下面代码的运行结果。点评:下面的程序对实际开发并没有什么意义,但却是CPython中的一个大坑,这道题旨在考察面试者对官方的Python解释器到底了解到什么程度。a, b, c, d = 1, 1, 1000, 1000print(a is b, c is d)def foo():    e = 1000    f = 1000    print(e is f, e is d)    g = 1    print(g is a)foo()运行结果:True FalseTrue FalseTrue上面代码中a is b的结果是True但c is d的结果是False,这一点的确让人费解。CPython解释器出于性能优化的考虑,把频繁使用的整数对象用一个叫small_ints的对象池缓存起来造成的。small_ints缓存的整数值被设定为[-5, 256]这个区间,也就是说,在任何引用这些整数的地方,都不需要重新创建int对象,而是直接引用缓存池中的对象。如果整数不在该范围内,那么即便两个整数的值相同,它们也是不同的对象。CPython底层为了进一步提升性能还做了另一个设定,对于同一个代码块中值不在small_ints缓存范围内的整数,如果同一个代码块中已经存在一个值与其相同的整数对象,那么就直接引用该对象,否则创建新的int对象。需要大家注意的是,这条规则对数值型适用,但对字符串则需要考虑字符串的长度,这一点大家可以自行证明。扩展:如果你用PyPy(另一种Python解释器实现,支持JIT,对CPython的缺点进行了改良,在性能上优于CPython,但对三方库的支持略差)来运行上面的代码,你会发现所有的输出都是True。题目005:Lambda函数是什么,举例说明的它的应用场景。点评:这个题目主要想考察的是Lambda函数的应用场景,潜台词是问你在项目中有没有使用过Lambda函数,具体在什么场景下会用到Lambda函数,借此来判断你写代码的能力。因为Lambda函数通常用在高阶函数中,主要的作用是通过向函数传入函数或让函数返回函数最终实现代码的解耦合。Lambda函数也叫匿名函数,它是功能简单用一行代码就能实现的小型函数。Python中的Lambda函数只能写一个表达式,这个表达式的执行结果就是函数的返回值,不用写return关键字。Lambda函数因为没有名字,所以也不会跟其他函数发生命名冲突的问题。扩展:面试的时候有可能还会考你用Lambda函数来实现一些功能,也就是用一行代码来实现题目要求的功能,例如:用一行代码实现求阶乘的函数,用一行代码实现求最大公约数的函数等。fac = lambda x: __import__('functools').reduce(int.__mul__, range(1, x + 1), 1)gcd = lambda x, y: y % x and gcd(y % x, x) or xLambda函数其实最为主要的用途是把一个函数传入另一个高阶函数(如Python内置的filter、map等)中来为函数做解耦合,增强函数的灵活性和通用性。下面的例子通过使用filter和map函数,实现了从列表中筛选出奇数并求平方构成新列表的操作,因为用到了高阶函数,过滤和映射数据的规则都是函数的调用者通过另外一个函数传入的,因此这filter和map函数没有跟特定的过滤和映射数据的规则耦合在一起。items = [12, 5, 7, 10, 8, 19]items = list(map(lambda x: x ** 2, filter(lambda x: x % 2, items)))print(items)    # [25, 49, 361]扩展:用列表的生成式来实现上面的代码会更加简单明了,代码如下所示。items = [12, 5, 7, 10, 8, 19]items = [x ** 2 for x in items if x % 2]print(items)    # [25, 49, 361]题目006:说说Python中的浅拷贝和深拷贝。点评:这个题目本身出现的频率非常高,但是就题论题而言没有什么技术含量。对于这种面试题,在回答的时候一定要让你的答案能够超出面试官的预期,这样才能获得更好的印象分。所以回答这个题目的要点不仅仅是能够说出浅拷贝和深拷贝的区别,深拷贝的时候可能遇到的两大问题,还要说出Python标准库对浅拷贝和深拷贝的支持,然后可以说说列表、字典如何实现拷贝操作以及如何通过序列化和反序列的方式实现深拷贝,最后还可以提到设计模式中的原型模式以及它在项目中的应用。浅拷贝通常只复制对象本身,而深拷贝不仅会复制对象,还会递归的复制对象所关联的对象。深拷贝可能会遇到两个问题:一是一个对象如果直接或间接的引用了自身,会导致无休止的递归拷贝;二是深拷贝可能对原本设计为多个对象共享的数据也进行拷贝。Python通过copy模块中的copy和deepcopy函数来实现浅拷贝和深拷贝操作,其中deepcopy可以通过memo字典来保存已经拷贝过的对象,从而避免刚才所说的自引用递归问题;此外,可以通过copyreg模块的pickle函数来定制指定类型对象的拷贝行为。deepcopy函数的本质其实就是对象的一次序列化和一次返回序列化,面试题中还考过用自定义函数实现对象的深拷贝操作,显然我们可以使用pickle模块的dumps和loads来做到,代码如下所示。import picklemy_deep_copy = lambda obj: pickle.loads(pickle.dumps(obj))列表的切片操作[:]相当于实现了列表对象的浅拷贝,而字典的copy方法可以实现字典对象的浅拷贝。对象拷贝其实是更为快捷的创建对象的方式。在Python中,通过构造器创建对象属于两阶段构造,首先是分配内存空间,然后是初始化。在创建对象时,我们也可以基于“原型”对象来创建新对象,通过对原型对象的拷贝(复制内存)就完成了对象的创建和初始化,这种做法更加高效,这也就是设计模式中的原型模式。在Python中,我们可以通过元类的方式来实现原型模式,代码如下所示。import copyclass PrototypeMeta(type):    """实现原型模式的元类"""    def __init__(cls, *args, **kwargs):        super().__init__(*args, **kwargs)        # 为对象绑定clone方法来实现对象拷贝        cls.clone = lambda self, is_deep=True: \            copy.deepcopy(self) if is_deep else copy.copy(self)class Person(metaclass=PrototypeMeta):    passp1 = Person()p2 = p1.clone()                 # 深拷贝p3 = p1.clone(is_deep=False)    # 浅拷贝题目007:Python是如何实现内存管理的?点评:当面试官问到这个问题的时候,一个展示自己的机会就摆在面前了。你要先反问面试官:“你说的是官方的CPython解释器吗?”。这个反问可以展示出你了解过Python解释器的不同的实现版本,而且你也知道面试官想问的是CPython。当然,很多面试官对不同的Python解释器底层实现到底有什么差别也没有概念。所以,千万不要觉得面试官一定比你强,怀揣着这份自信可以让你更好的完成面试。Python提供了自动化的内存管理,也就是说内存空间的分配与释放都是由Python解释器在运行时自动进行的,自动管理内存功能极大的减轻程序员的工作负担,也能够帮助程序员在一定程度上解决内存泄露的问题。以CPython解释器为例,它的内存管理有三个关键点:引用计数、标记清理、分代收集。引用计数:对于CPython解释器来说,Python中的每一个对象其实就是PyObject结构体,它的内部有一个名为ob_refcnt 的引用计数器成员变量。程序在运行的过程中ob_refcnt的值会被更新并藉此来反映引用有多少个变量引用到该对象。当对象的引用计数值为0时,它的内存就会被释放掉。typedef struct _object {    _PyObject_HEAD_EXTRA    Py_ssize_t ob_refcnt;    struct _typeobject *ob_type;} PyObject;以下情况会导致引用计数加1:对象被创建对象被引用对象作为参数传入到一个函数中对象作为元素存储到一个容器中以下情况会导致引用计数减1:用del语句显示删除对象引用对象引用被重新赋值其他对象一个对象离开它所在的作用域持有该对象的容器自身被销毁持有该对象的容器删除该对象可以通过sys模块的getrefcount函数来获得对象的引用计数。引用计数的内存管理方式在遇到循环引用的时候就会出现致命伤,因此需要其他的垃圾回收算法对其进行补充。标记清理:CPython使用了“标记-清理”(Mark and Sweep)算法解决容器类型可能产生的循环引用问题。该算法在垃圾回收时分为两个阶段:标记阶段,遍历所有的对象,如果对象是可达的(被其他对象引用),那么就标记该对象为可达;清除阶段,再次遍历对象,如果发现某个对象没有标记为可达,则就将其回收。CPython底层维护了两个双端链表,一个链表存放着需要被扫描的容器对象(姑且称之为链表A),另一个链表存放着临时不可达对象(姑且称之为链表B)。为了实现“标记-清理”算法,链表中的每个节点除了有记录当前引用计数的ref_count变量外,还有一个gc_ref变量,这个gc_ref是ref_count的一个副本,所以初始值为ref_count的大小。执行垃圾回收时,首先遍历链表A中的节点,并且将当前对象所引用的所有对象的gc_ref减1,这一步主要作用是解除循环引用对引用计数的影响。再次遍历链表A中的节点,如果节点的gc_ref值为0,那么这个对象就被标记为“暂时不可达”(GC_TENTATIVELY_UNREACHABLE)并被移动到链表B中;如果节点的gc_ref不为0,那么这个对象就会被标记为“可达“(GC_REACHABLE),对于”可达“对象,还要递归的将该节点可以到达的节点标记为”可达“;链表B中被标记为”可达“的节点要重新放回到链表A中。在两次遍历之后,链表B中的节点就是需要释放内存的节点。分代回收:在循环引用对象的回收中,整个应用程序会被暂停,为了减少应用程序暂停的时间,Python 通过分代回收(空间换时间)的方法提高垃圾回收效率。分代回收的基本思想是:对象存在的时间越长,是垃圾的可能性就越小,应该尽量不对这样的对象进行垃圾回收。CPython将对象分为三种世代分别记为0、1、2,每一个新生对象都在第0代中,如果该对象在一轮垃圾回收扫描中存活下来,那么它将被移到第1代中,存在于第1代的对象将较少的被垃圾回收扫描到;如果在对第1代进行垃圾回收扫描时,这个对象又存活下来,那么它将被移至第2代中,在那里它被垃圾回收扫描的次数将会更少。分代回收扫描的门限值可以通过gc模块的get_threshold函数来获得,该函数返回一个三元组,分别表示多少次内存分配操作后会执行0代垃圾回收,多少次0代垃圾回收后会执行1代垃圾回收,多少次1代垃圾回收后会执行2代垃圾回收。需要说明的是,如果执行一次2代垃圾回收,那么比它年轻的代都要执行垃圾回收。如果想修改这几个门限值,可以通过gc模块的set_threshold函数来做到。题目008:说一下你对Python中迭代器和生成器的理解。点评:很多人面试者都会写迭代器和生成器,但是却无法准确的解释什么是迭代器和生成器。如果你也有同样的困惑,可以参考下面的回答。迭代器是实现了迭代器协议的对象。跟其他编程语言不通,Python中没有用于定义协议或表示约定的关键字,像interface、protocol这些单词并不在Python语言的关键字列表中。Python语言通过魔法方法来表示约定,也就是我们所说的协议,而__next__和__iter__这两个魔法方法就代表了迭代器协议。可以通过for-in循环从迭代器对象中取出值,也可以使用next函数取出迭代器对象中的下一个值。生成器是迭代器的语法升级版本,可以用更为简单的代码来实现一个迭代器。扩展:面试中经常让写生成斐波那契数列的迭代器,大家可以参考下面的代码。class Fib(object):        def __init__(self, num):        self.num = num        self.a, self.b = 0, 1        self.idx = 0       def __iter__(self):        return self    def __next__(self):        if self.idx < self.num:            self.a, self.b = self.b, self.a + self.b            self.idx += 1            return self.a        raise StopIteration()如果用生成器的语法来改写上面的代码,代码会简单优雅很多。def fib(num):    a, b = 0, 1    for _ in range(num):        a, b = b, a + b        yield a题目009:正则表达式的match方法和search方法有什么区别?点评:正则表达式是字符串处理的重要工具,所以也是面试中经常考察的知识点。在Python中,使用正则表达式有两种方式,一种是直接调用re模块中的函数,传入正则表达式和需要处理的字符串;一种是先通过re模块的compile函数创建正则表达式对象,然后再通过对象调用方法并传入需要处理的字符串。如果一个正则表达式被频繁的使用,我们推荐用re.compile函数创建正则表达式对象,这样会减少频繁编译同一个正则表达式所造成的开销。match方法是从字符串的起始位置进行正则表达式匹配,返回Match对象或None。search方法会扫描整个字符串来找寻匹配的模式,同样也是返回Match对象或None。题目010:下面这段代码的执行结果是什么。def multiply():    return [lambda x: i * x for i in range(4)]print([m(100) for m in multiply()])运行结果:[300, 300, 300, 300]1上面代码的运行结果很容易被误判为[0, 100, 200, 300]。首先需要注意的是multiply函数用生成式语法返回了一个列表,列表中保存了4个Lambda函数,这4个Lambda函数会返回传入的参数乘以i的结果。需要注意的是这里有闭包(closure)现象,multiply函数中的局部变量i的生命周期被延展了,由于i最终的值是3,所以通过m(100)调列表中的Lambda函数时会返回300,而且4个调用都是如此。如果想得到[0, 100, 200, 300]这个结果,可以按照下面几种方式来修改multiply函数。方法一:使用生成器,让函数获得i的当前值。def multiply():    return (lambda x: i * x for i in range(4))print([m(100) for m in multiply()])或者def multiply():    for i in range(4):        yield lambda x: x * iprint([m(100) for m in multiply()])方法二:使用偏函数,彻底避开闭包。from functools import partialfrom operator import __mul__def multiply():    return [partial(__mul__, i) for i in range(4)]print([m(100) for m in multiply()])题目011:Python中为什么没有函数重载?点评:C++、Java、C#等诸多编程语言都支持函数重载,所谓函数重载指的是在同一个作用域中有多个同名函数,它们拥有不同的参数列表(参数个数不同或参数类型不同或二者皆不同),可以相互区分。重载也是一种多态性,因为通常是在编译时通过参数的个数和类型来确定到底调用哪个重载函数,所以也被称为编译时多态性或者叫前绑定。这个问题的潜台词其实是问面试者是否有其他编程语言的经验,是否理解Python是动态类型语言,是否知道Python中函数的可变参数、关键字参数这些概念。首先Python是解释型语言,函数重载现象通常出现在编译型语言中。其次Python是动态类型语言,函数的参数没有类型约束,也就无法根据参数类型来区分重载。再者Python中函数的参数可以有默认值,可以使用可变参数和关键字参数,因此即便没有函数重载,也要可以让一个函数根据调用者传入的参数产生不同的行为。题目012:用Python代码实现Python内置函数max。点评:这个题目看似简单,但实际上还是比较考察面试者的功底。因为Python内置的max函数既可以传入可迭代对象找出最大,又可以传入两个或多个参数找出最大;最为关键的是还可以通过命名关键字参数key来指定一个用于元素比较的函数,还可以通过default命名关键字参数来指定当可迭代对象为空时返回的默认值。下面的代码仅供参考:def my_max(*args, key=None, default=None):    """    获取可迭代对象中最大的元素或两个及以上实参中最大的元素    :param args: 一个可迭代对象或多个元素    :param key: 提取用于元素比较的特征值的函数,默认为None    :param default: 如果可迭代对象为空则返回该默认值,如果没有给默认值则引发ValueError异常    :return: 返回可迭代对象或多个元素中的最大元素    """    if len(args) == 1 and len(args[0]) == 0:        if default:            return default        else:            raise ValueError('max() arg is an empty sequence')    items = args[0] if len(args) == 1 else args    max_elem, max_value = items[0], items[0]    if key:        max_value = key(max_value)    for item in items:        value = item        if key:            value = key(item)        if value > max_value:            max_elem, max_value = item, value题目013:写一个函数统计传入的列表中每个数字出现的次数并返回对应的字典。点评:送人头的题目,不解释。def count_letters(items):    result = {}    for item in items:        if isinstance(item, (int, float)):            result[item] = result.get(item, 0) + 1    return result也可以直接使用Python标准库中collections模块的Counter类来解决这个问题,Counter是dict的子类,它会将传入的序列中的每个元素作为键,元素出现的次数作为值来构造字典。from collections import Counterdef count_letters(items):    counter = Counter(items)    return {key: value for key, value in counter.items() \            if isinstance(key, (int, float))}题目014:使用Python代码实现遍历一个文件夹的操作。点评:基本也是送人头的题目,只要用过os模块就应该知道怎么做。Python标准库os模块的walk函数提供了遍历一个文件夹的功能,它返回一个生成器。import osg = os.walk('/Users/Hao/Downloads/')for path, dir_list, file_list in g:    for dir_name in dir_list:        print(os.path.join(path, dir_name))    for file_name in file_list:        print(os.path.join(path, file_name))说明:os.path模块提供了很多进行路径操作的工具函数,在项目开发中也是经常会用到的。如果题目明确要求不能使用os.walk函数,那么可以使用os.listdir函数来获取指定目录下的文件和文件夹,然后再通过循环遍历用os.isdir函数判断哪些是文件夹,对于文件夹可以通过递归调用进行遍历,这样也可以实现遍历一个文件夹的操作。题目015:现有2元、3元、5元共三种面额的货币,如果需要找零99元,一共有多少种找零的方式?点评:还有一个非常类似的题目:“一个小朋友走楼梯,一次可以走1个台阶、2个台阶或3个台阶,问走完10个台阶一共有多少种走法?”,这两个题目的思路是一样,如果用递归函数来写的话非常简单。from functools import lru_cache@lru_cache()def change_money(total):    if total == 0:        return 1    if total < 0:        return 0    return change_money(total - 2) + change_money(total - 3) + \        change_money(total - 5)说明:在上面的代码中,我们用lru_cache装饰器装饰了递归函数change_money,如果不做这个优化,上面代码的渐近时间复杂度将会是O ( 3 N ) O(3^N)O(3 N ),而如果参数total的值是99,这个运算量是非常巨大的。lru_cache装饰器会缓存函数的执行结果,这样就可以减少重复运算所造成的开销,这是空间换时间的策略,也是动态规划的编程思想。题目016:写一个函数,给定矩阵的阶数n,输出一个螺旋式数字矩阵。例如:n = 2,返回:1 24 312例如:n = 3,返回:1 2 38 9 47 6 5这个题目本身并不复杂,下面的代码仅供参考。def show_spiral_matrix(n):    matrix = [[0] * n for _ in range(n)]    row, col = 0, 0    num, direction = 1, 0    while num <= n ** 2:        if matrix[row][col] == 0:            matrix[row][col] = num            num += 1        if direction == 0:            if col < n - 1 and matrix[row][col + 1] == 0:                col += 1            else:                direction += 1        elif direction == 1:            if row < n - 1 and matrix[row + 1][col] == 0:                row += 1            else:                direction += 1        elif direction == 2:            if col > 0 and matrix[row][col - 1] == 0:                col -= 1            else:                direction += 1        else:            if row > 0 and matrix[row - 1][col] == 0:                row -= 1            else:                direction += 1        direction %= 4    for x in matrix:        for y in x:            print(y, end='\t')        print()题目017:阅读下面的代码,写出程序的运行结果。items = [1, 2, 3, 4] print([i for i in items if i > 2])print([i for i in items if i % 2])print([(x, y) for x, y in zip('abcd', (1, 2, 3, 4, 5))])print({x: f'item{x ** 2}' for x in (2, 4, 6)})print(len({x for x in 'hello world' if x not in 'abcdefg'}))点评:生成式(推导式)属于Python的特色语法之一,几乎是面试必考内容。Python中通过生成式字面量语法,可以创建出列表、集合、字典。[3, 4][1, 3][('a', 1), ('b', 2), ('c', 3), ('d', 4)]{2: 'item4', 4: 'item16', 6: 'item36'}6题目018:说出下面代码的运行结果。class Parent:    x = 1class Child1(Parent):    passclass Child2(Parent):    passprint(Parent.x, Child1.x, Child2.x)Child1.x = 2print(Parent.x, Child1.x, Child2.x)Parent.x = 3print(Parent.x, Child1.x, Child2.x)点评:运行上面的代码首先输出1 1 1,这一点大家应该没有什么疑问。接下来,通过Child1.x = 2给类Child1重新绑定了属性x并赋值为2,所以Child1.x会输出2,而Parent和Child2并不受影响。执行Parent.x = 3会重新给Parent类的x属性赋值为3,由于Child2的x属性继承自Parent,所以Child2.x的值也是3;而之前我们为Child1重新绑定了x属性,那么它的x属性值不会受到Parent.x = 3的影响,还是之前的值2。1 1 11 2 13 2 3123题目19:说说你用过Python标准库中的哪些模块。点评:Python标准库中的模块非常多,建议大家根据自己过往的项目经历来介绍你用过的标准库和三方库,因为这些是你最为熟悉的,经得起面试官深挖的。模块名 介绍sys 跟Python解释器相关的变量和函数,例如:sys.version、sys.exit()os 和操作系统相关的功能,例如:os.listdir()、os.remove()re 和正则表达式相关的功能,例如:re.compile()、re.search()math 和数学运算相关的功能,例如:math.pi、math.e、math.coslogging 和日志系统相关的类和函数,例如:logging.Logger、logging.Handlerjson / pickle 实现对象序列化和反序列的模块,例如:json.loads、json.dumpshashlib 封装了多种哈希摘要算法的模块,例如:hashlib.md5、hashlib.sha1urllib 包含了和URL相关的子模块,例如:urllib.request、urllib.parseitertools 提供各种迭代器的模块,例如:itertools.cycle、itertools.productfunctools 函数相关工具模块,例如:functools.partial、functools.lru_cachecollections / heapq 封装了常用数据结构和算法的模块,例如:collections.dequethreading / multiprocessing 多线程/多进程相关类和函数的模块,例如:threading.Threadconcurrent.futures / asyncio 并发编程/异步编程相关的类和函数的模块,例如:ThreadPoolExecutorbase64 提供BASE-64编码相关函数的模块,例如:bas64.encodecsv 和读写CSV文件相关的模块,例如:csv.reader、csv.writerprofile / cProfile / pstats 和代码性能剖析相关的模块,例如:cProfile.run、pstats.Statsunittest 和单元测试相关的模块,例如:unittest.TestCase题目20:__init__和__new__方法有什么区别?Python中调用构造器创建对象属于两阶段构造过程,首先执行__new__方法获得保存对象所需的内存空间,再通过__init__执行对内存空间数据的填充(对象属性的初始化)。__new__方法的返回值是创建好的Python对象(的引用),而__init__方法的第一个参数就是这个对象(的引用),所以在__init__中可以完成对对象的初始化操作。__new__是类方法,它的第一个参数是类,__init__是对象方法,它的第一个参数是对象。题目21:输入年月日,判断这个日期是这一年的第几天。方法一:不使用标准库中的模块和函数。def is_leap_year(year):    """判断指定的年份是不是闰年,平年返回False,闰年返回True"""    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0def which_day(year, month, date):    """计算传入的日期是这一年的第几天"""    # 用嵌套的列表保存平年和闰年每个月的天数    days_of_month = [        [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],        [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]    ]    days = days_of_month[is_leap_year(year)][:month - 1]    return sum(days) + date方法二:使用标准库中的datetime模块。import datetimedef which_day(year, month, date):    end = datetime.date(year, month, date)    start = datetime.date(year, 1, 1)    return (end - start).days + 1题目22:平常工作中用什么工具进行静态代码分析。点评:静态代码分析工具可以从代码中提炼出各种静态属性,这使得开发者可以对代码的复杂性、可维护性和可读性有更好的了解,这里所说的静态属性包括:代码是否符合编码规范,例如:PEP-8。代码中潜在的问题,包括:语法错误、缩进问题、导入缺失、变量覆盖等。代码中的坏味道。代码的复杂度。代码的逻辑问题。工作中静态代码分析主要用到的是Pylint和Flake8。Pylint可以检查出代码错误、坏味道、不规范的代码等问题,较新的版本中还提供了代码复杂度统计数据,可以生成检查报告。Flake8封装了Pyflakes(检查代码逻辑错误)、McCabe(检查代码复杂性)和Pycodestyle(检查代码是否符合PEP-8规范)工具,它可以执行这三个工具提供的检查。题目23:说一下你知道的Python中的魔术方法。点评:魔术方法也称为魔法方法,是Python中的特色语法,也是面试中的高频问题。魔术方法 作用__new__、__init__、__del__ 创建和销毁对象相关__add__、__sub__、__mul__、__div__、__floordiv__、__mod__ 算术运算符相关__eq__、__ne__、__lt__、__gt__、__le__、__ge__ 关系运算符相关__pos__、__neg__、__invert__ 一元运算符相关__lshift__、__rshift__、__and__、__or__、__xor__ 位运算相关__enter__、__exit__ 上下文管理器协议__iter__、__next__、__reversed__ 迭代器协议__int__、__long__、__float__、__oct__、__hex__ 类型/进制转换相关__str__、__repr__、__hash__、__dir__ 对象表述相关__len__、__getitem__、__setitem__、__contains__、__missing__ 序列相关__copy__、__deepcopy__ 对象拷贝相关__call__、__setattr__、__getattr__、__delattr__ 其他魔术方法题目24:函数参数*arg和**kwargs分别代表什么?Python中,函数的参数分为位置参数、可变参数、关键字参数、命名关键字参数。*args代表可变参数,可以接收0个或任意多个参数,当不确定调用者会传入多少个位置参数时,就可以使用可变参数,它会将传入的参数打包成一个元组。**kwargs代表关键字参数,可以接收用参数名=参数值的方式传入的参数,传入的参数的会打包成一个字典。定义函数时如果同时使用*args和**kwargs,那么函数可以接收任意参数。题目25:写一个记录函数执行时间的装饰器。点评:高频面试题,也是最简单的装饰器,面试者必须要掌握的内容。方法一:用函数实现装饰器。from functools import wrapsfrom time import timedef record_time(func):        @wraps(func)    def wrapper(*args, **kwargs):        start = time()        result = func(*args, **kwargs)        print(f'{func.__name__}执行时间: {time() - start}秒')        return result            return wrapper方法二:用类实现装饰器。类有__call__魔术方法,该类对象就是可调用对象,可以当做装饰器来使用。from functools import wrapsfrom time import timeclass Record:        def __call__(self, func):                @wraps(func)        def wrapper(*args, **kwargs):            start = time()            result = func(*args, **kwargs)            print(f'{func.__name__}执行时间: {time() - start}秒')            return result                return wrapper说明:装饰器可以用来装饰类或函数,为其提供额外的能力,属于设计模式中的代理模式。扩展:装饰器本身也可以参数化,例如上面的例子中,如果不希望在终端中显示函数的执行时间而是希望由调用者来决定如何输出函数的执行时间,可以通过参数化装饰器的方式来做到,代码如下所示。from functools import wrapsfrom time import timedef record_time(output):    """可以参数化的装饰器"""def decorate(func):@wraps(func)def wrapper(*args, **kwargs):start = time()result = func(*args, **kwargs)output(func.__name__, time() - start)return result            return wrapperreturn decorate题目26:什么是鸭子类型(duck typing)?鸭子类型是动态类型语言判断一个对象是不是某种类型时使用的方法,也叫做鸭子判定法。简单的说,鸭子类型是指判断一只鸟是不是鸭子,我们只关心它游泳像不像鸭子、叫起来像不像鸭子、走路像不像鸭子就足够了。换言之,如果对象的行为跟我们的预期是一致的(能够接受某些消息),我们就认定它是某种类型的对象。在Python语言中,有很多bytes-like对象(如:bytes、bytearray、array.array、memoryview)、file-like对象(如:StringIO、BytesIO、GzipFile、socket)、path-like对象(如:str、bytes),其中file-like对象都能支持read和write操作,可以像文件一样读写,这就是所谓的对象有鸭子的行为就可以判定为鸭子的判定方法。再比如Python中列表的extend方法,它需要的参数并不一定要是列表,只要是可迭代对象就没有问题。说明:动态语言的鸭子类型使得设计模式的应用被大大简化。————————————————版权声明:本文为CSDN博主「五包辣条!」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/AI19970205/article/details/125182872
  • [其他] 浅谈Pandas的优点
    Pandas是python的一个数据分析包,最初由AQR Capital Management于2008年4月开发,并于2009年底开源出来,目前由专注于Python数据包开发的PyData开发team继续开发和维护,属于PyData项目的一部分。Pandas最初被作为金融数据分析工具而开发出来,因此,pandas为时间序列分析提供了很好的支持。 Pandas的名称来自于面板数据(panel data)和python数据分析(data analysis)。panel data是经济学中关于多维数据集的一个术语,在Pandas中也提供了panel的数据类型。Pandas有许多的优势    处理浮点与非浮点数据里的缺失数据,表示为NaN;    大小可变:插入或删除DataFrame等多维对象的列;    自动、显示数据对齐:显示将对象与一组标签对齐,也可以忽略标签,在Series、DataFrame计算时自动与数据对齐;    强大、灵活的分组(group by)功能:拆分-应用-组合数据集,聚合、转换数据;    把Python和NumPy数据结构里不规则、不同索引的数据轻松地转换为DataFrame对象;    基于智能标签,对大型数据集进行切片、花式索引、子集分解等操作;    直观地合并、连接数据集;    灵活地重构、透视数据集;    轴支持结构化标签:一个刻度支持多个标签;    成熟地IO工具:读取文本文件(CSV等支持分隔符地文件)、Excel文件、数据库等来源地数据,利用超快地HDF5格式保存/加载数据;    时间序列:支持日期范围生成、频率转换、移动窗口统计、移动窗口线性回归、日期位移等时间序列功能。这些功能主要是为了解决其它编程语言、科研环境的痛点。处理数据一般分为数据整理与清洗、数据分析与建模、数据可视化与制表,Pandas是处理数据的理想工具。Pandas速度很快,Pandas很多底层算法都用Cython优化过。然而,为了保持通用性,必然要牺牲一些性能,如果专注某一功能,完全可以开发出比Pandas更快的专用工具。Pandas是statsmodels的依赖项,因此,Pandas也是Python中统计计算生态系统的重要组成部分。Pandas已广泛应用于金融领域。
  • [其他] 浅谈Python解释器种类
         Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆 于1990 年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言,随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python 也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器码。 2021年10月,语言流行指数的编译器Tiobe将Python加冕为最受欢迎的编程语言,20年来首次将其置于Java、C和JavaScript之上Python解释器种类    Cpython:用C语言开发的,在命令行下运行Python就是启动Cpython解释器,官方下载的python2.7均为Cpython。Cpython用>>>作为提示符。    Ipython:基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的。IPython用In [序号]:作为提示符。    PyPy:主要针对执行速度。采用JIT技术,对Python代码进行动态编译。绝大部分Python代码都可以在PyPy下运行。    Jpython:运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。    IronPython:运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。    Boost.Python:使得Python和C++的类库可互相调用(.pyc)
总条数:2474 到第 页
上滑加载中