持续集成交付CICD:GitLabCI 封装Python类 并结合 ArgoCD 完成前端项目应用发布

目录

一、实验

1. 环境

2. Python代码实现获取文件

3.Python代码实现创建文件

4.Python代码实现更新文件

5.GitLab更新库文件与运行流水线

6.ArgoCD 完成前端项目应用发布

二、问题

1.Python获取GitLab指定仓库文件报错

2. K8S master节点运行Python代码报错


一、实验

1. 环境

(1)主机

表1 主机

主机架构版本IP备注
master1K8S master节点1.20.6192.168.204.180

jenkins slave

(从节点)

argocd2.9.3192.168.204.180:31767
node1K8S node节点1.20.6192.168.204.181
node2K8S node节点1.20.6192.168.204.182
jenkins

 jenkins主节点      

2.414.2192.168.204.15:8080

 gitlab runner

(从节点)

harbor私有仓库1.2.2192.168.204.15
python2.7.5系统自带
gitlabgitlab 主节点     12.10.14192.168.204.8:82

jenkins slave

(从节点)

sonarqube9.6192.168.204.8:9000

2. Python代码实现获取文件

(1) GitLab官网查询通过API操作获取raw文件

Repository files API | GitLab

curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fmodels%2Fkey%2Erb/raw?ref=main"


(2)GitLab 创建TOKEN

(3)GitLab查看项目编号

(4)Postman测试完成,转换成Python代码

import requests

url = "http://192.168.204.8:82/api/v4/projects/22/repository/files/deployment.yaml/raw?ref=master"

payload = {}
headers = {
  'PRIVATE-TOKEN': 'Z6RKxDgK7ort7i9K6f6p'
}

response = requests.request("GET", url, headers=headers, data=payload)

print(response.text)

(3)python实现获取GitLab指定仓库deplyment.yaml文件

import requests
import json

class GitlabUtil():
    def __init__(self):
        self.gitlab_url = "http://192.168.204.8:82/api/v4"
        self.headers = {'PRIVATE-TOKEN': 'Z6RKxDgK7ort7i9K6f6p'}

    def http_req(self,method,apiUrl,data={}):
        url = "{0}/{1}".format(self.gitlab_url,apiUrl)
        response = requests.request(method,url,headers=self.headers,data=data)
        return response.text

    def write_file(self,content,filePath):
        with open(filePath,'w') as f:
            f.write(content)

    def get_repo_file(self,projectId,filePath,branch,targetFile):
        apiurl = "projects/{0}/repository/files/{1}/raw?ref={2}".format(projectId,filePath,branch)

        response = self.http_req("GET",apiurl)
        # print(response.txt)
        self.write_file(response,targetFile)

if __name__ == '__main__':
    runner = GitlabUtil()
    runner.get_repo_file("22","deployment.yaml","master","deployment.yaml")

(4)运行Python代码(Windows11 Python环境为3.8)

(5)本地生成deployment.yaml

(6)K8S master节点同样运行Python代码进行测试(Python环境为2.7)

1)创建目录及python文件
# mkdir pygitlabtest
# cd pygitlabtest/
# vim test.py
# ls

2)查看版本
# python --version

3)运行代码
# python test.py 

3.Python代码实现创建文件

(1)GitLab官网查询通过API操作在指定仓库创建文件

curl --request POST --header 'PRIVATE-TOKEN: <your_access_token>' \
     --header "Content-Type: application/json" \
     --data '{"branch": "main", "author_email": "author@example.com", "author_name": "Firstname Lastname",
               "content": "some content", "commit_message": "create a new file"}' \
     "https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fproject%2Erb"

(2)Postman测试完成,转换成Python代码

import requests
import json

url = "http://192.168.204.8:82/api/v4/projects/22/repository/files/demo.yaml"

payload = json.dumps({
  "branch": "master",
  "content": "Hello World",
  "commit_message": "commmit by autorobot"
})
headers = {
  'PRIVATE-TOKEN': 'Z6RKxDgK7ort7i9K6f6p',
  'Content-Type': 'application/json'
}

response = requests.request("POST", url, headers=headers, data=payload)

print(response.text)

(3)GitLab查看项目生成了demo.yaml文件

(4)python实现在GitLab指定项目创建demo02.yaml文件

# -*- coding: utf-8 -*-
import requests
import json
import base64

class GitlabUtil():
    def __init__(self,projectId):
        self.gitlab_url = "http://192.168.204.8:82/api/v4"
        self.gitlab_token = 'Z6RKxDgK7ort7i9K6f6p'
        self.projectId = projectId
        self.encoding = "base64"

    def http_req(self,method,apiUrl,headers,data):
        url = "{0}/{1}".format(self.gitlab_url,apiUrl)
        response = requests.request(method,url,headers=headers,data=data)
        return response.text

    def write_file(self,content,filePath):
        with open(filePath,'w') as f:
            f.write(content)

    def get_repo_file(self,filePath,branch,targetFile):
        apiurl = "projects/{0}/repository/files/{1}/raw?ref={2}".format(self.projectId,filePath,branch)
        headers = {
            'PRIVATE-TOKEN': self.gitlab_token,
            'Content-Type': 'application/json'
        }
        response = self.http_req("GET",apiurl,headers, {})
        # print(response.txt)
        self.write_file(response,targetFile)

    def create_repo_file(self,filePath,branch,content,commit_message):
        apiurl = "/projects/{0}/repository/files/{1}".format(self.projectId,filePath)

        data = json.dumps({
            "branch": branch,
            "content": content,
            "commit_message": commit_message
            # "encoding": self.encoding
        })

        headers = {
            'PRIVATE-TOKEN': self.gitlab_token,
            'Content-Type': 'application/json'
        }

        self.http_req("POST", apiurl,headers=headers,data=data)


if __name__ == '__main__':
    runner = GitlabUtil("22")
    # runner.get_repo_file("deployment.yaml","master","deployment.yaml")

    f = open("deployment.yaml",'r',encoding='utf-8')
    content = f.read()
    f.close()
    # content = base64.b64encode(bytes(content,"utf-8"))

    runner.create_repo_file("demo02.yaml","master",content,"Hello World 2")

(5)运行Python代码(Windows11 Python环境为3.8)

(6)GitLab查看项目生成了demo2.yaml文件

4.Python代码实现更新文件

(1)GitLab官网查询通过API操作在指定仓库更新文件

curl --request PUT --header 'PRIVATE-TOKEN: <your_access_token>' \
     --header "Content-Type: application/json" \
     --data '{"branch": "main", "author_email": "author@example.com", "author_name": "Firstname Lastname",
       "content": "some content", "commit_message": "update file"}' \
     "https://gitlab.example.com/api/v4/projects/13083/repository/files/app%2Fproject%2Erb"

(2)python实现在GitLab指定项目更新demo02.yaml文件

# -*- coding: utf-8 -*-
import requests
import json
import base64

class GitlabUtil():
    def __init__(self,projectId):
        self.gitlab_url = "http://192.168.204.8:82/api/v4"
        self.gitlab_token = 'Z6RKxDgK7ort7i9K6f6p'
        self.projectId = projectId
        self.encoding = "base64"

    def http_req(self,method,apiUrl,headers,data):
        url = "{0}/{1}".format(self.gitlab_url,apiUrl)
        response = requests.request(method,url,headers=headers,data=data)
        return response.text

    def write_file(self,content,filePath):
        with open(filePath,'w') as f:
            f.write(content)

    # 下载文件
    def get_repo_file(self,filePath,branch,targetFile):
        apiurl = "projects/{0}/repository/files/{1}/raw?ref={2}".format(self.projectId,filePath,branch)
        headers = {
            'PRIVATE-TOKEN': self.gitlab_token,
            'Content-Type': 'application/json'
        }
        response = self.http_req("GET",apiurl,headers, {})
        # print(response.txt)
        self.write_file(response,targetFile)

    # 创建文件
    def create_repo_file(self,filePath,branch,content,commit_message):
        apiurl = "/projects/{0}/repository/files/{1}".format(self.projectId,filePath)

        data = json.dumps({
            "branch": branch,
            "content": content,
            "commit_message": commit_message
            # "encoding": self.encoding
        })

        headers = {
            'PRIVATE-TOKEN': self.gitlab_token,
            'Content-Type': 'application/json'
        }

        self.http_req("POST", apiurl,headers=headers,data=data)

    # 更新文件
    def update_repo_file(self,filePath,branch,content,commit_message):
        apiurl = "/projects/{0}/repository/files/{1}".format(self.projectId,filePath)

        data = json.dumps({
            "branch": branch,
            "content": content,
            "commit_message": commit_message
            # "encoding": self.encoding
        })

        headers = {
            'PRIVATE-TOKEN': self.gitlab_token,
            'Content-Type': 'application/json'
        }

        self.http_req("PUT", apiurl,headers=headers,data=data)


if __name__ == '__main__':
    runner = GitlabUtil("22")
    # runner.get_repo_file("deployment.yaml","master","deployment.yaml")

    f = open("deployment.yaml",'r',encoding='utf-8')
    content = f.read()
    f.close()
    # content = base64.b64encode(bytes(content,"utf-8"))

    # runner.create_repo_file("demo02.yaml","master",content,"Hello World 2")
    runner.update_repo_file("demo02.yaml", "master", content, "Hello World 3")

(3)运行Python代码(Windows11 Python环境为3.8)

(4)GitLab查看项目更新了提交信息

5.GitLab更新库文件与运行流水线

(1)查看GitLab共享库

(2)新建流水线文件ui.gitlabutil.yaml

(3)复制raw格式

(4)在GitLab devops03-devops-env 环境库项目添加CI配置文件路径

(5)查看前端项目devops03-devops-ui 修改Dockerfile,注释本地CI流水线文件,避免后续运行错误

(6)查看前端项目目录下的index.html文件

(7) GitLab共享库新建目录util及GitLabUtil.py文件,用来封装python类

(8)GitLabUtil.py文件代码

import requests
import json
import base64
import sys

class GitlabUtil():
    def __init__(self,projectId):
        self.gitlab_url = "http://192.168.204.8:82/api/v4"
        self.gitlab_token = 'Z6RKxDgK7ort7i9K6f6p'
        self.projectId = projectId
        self.encoding = "base64"

    def http_req(self,method,apiUrl,headers,data):
        url = "{0}/{1}".format(self.gitlab_url,apiUrl)
        response = requests.request(method,url,headers=headers,data=data)
        return response.text

    def write_file(self,content,filePath):
        with open(filePath,'w') as f:
            f.write(content)

 
    def get_repo_file(self,filePath,branch,targetFile):
        apiurl = "projects/{0}/repository/files/{1}/raw?ref={2}".format(self.projectId,filePath,branch)
        headers = {
            'PRIVATE-TOKEN': self.gitlab_token,
            'Content-Type': 'application/json'
        }
        response = self.http_req("GET",apiurl,headers, {})
        # print(response.txt)
        self.write_file(response,targetFile)


    def create_repo_file(self,filePath,branch,content,commit_message):
        apiurl = "/projects/{0}/repository/files/{1}".format(self.projectId,filePath)

        data = json.dumps({
            "branch": branch,
            "content": content,
            "commit_message": commit_message
            # "encoding": self.encoding
        })

        headers = {
            'PRIVATE-TOKEN': self.gitlab_token,
            'Content-Type': 'application/json'
        }

        mes = self.http_req("POST", apiurl,headers=headers,data=data)
        if json.loads(mes)["message"] == "A file with this name already exists":
            raise Exception("A file with this name already exists")

  
    def update_repo_file(self,filePath,branch,content,commit_message):
        apiurl = "/projects/{0}/repository/files/{1}".format(self.projectId,filePath)

        data = json.dumps({
            "branch": branch,
            "content": content,
            "commit_message": commit_message

        })

        headers = {
            'PRIVATE-TOKEN': self.gitlab_token,
            'Content-Type': 'application/json'
        }

        self.http_req("PUT", apiurl,headers=headers,data=data)


if __name__ == '__main__':
    if sys.argv[1] == "getfile":
        projectId,filename,branch,targetFile = sys.argv[2:]
        GitlabUtil(projectId).get_repo_file(filename,branch,targetFile)

    if sys.argv[1] == "updatefile":
        projectId, filename, branch, targetFile = sys.argv[2:]
        f = open(filename, 'r')
        content = f.read()
        f.close()
        try:
            GitlabUtil(projectId).create_repo_file(targetFile, branch, content, "Auto K8S Deployment")
        except Exception as e:
            print(e)
            GitlabUtil(projectId).update_repo_file(targetFile, branch, content, "Auto K8S Deployment")

(9)修改流水线文件ui.gitlabutil.yaml

include:
 - project: 'devops03/devops03-gitlabci-lib'
   ref: master
   file: "/jobs/CI.yaml"


workflow:
  rules:
    #新建分支永远不执行
    - if: $CI_PIPELINE_SOURCE == "web"      #允许手动触发
      when: always
    - if: $CI_COMMIT_BEFORE_SHA == "0000000000000000000000000000000000000000"
      when: never
    # 其他情况永远执行
    - when: always

#取消每个阶段自动下载代码,即全局关闭作业代码下载
variables:
  GIT_CHECKOUT: "false"  ## 全局关闭作业代码下载
  PROJECT_TYPE: "npm"   ## 定义项目类型
                        
  BUILD_SHELL: "npm run build"   ## 构建命令
  TEST_SHELL: "echo test"                         ## 测试命令
  ARTIFACT_PATH: "dist/**"                                  ## 制品路径
 # TEST_REPORTS: "target/surefire-reports/TEST-*.xml"             ## 测试报告

stages:
  - build
  - sonarscan
  - dockerbuild
  - releasefile


pipelineInit:
  extends: 
    - .pipelineInit


cibuild:
  before_script:
   - "npm install"
  extends:
   - .cibuild

releasefile:
  tags:
    - build
  stage: releasefile
  script:
    - curl  "http://192.168.204.8:82/devops03/devops03-gitlabci-lib/-/raw/master/utils/GitLabUtil.py" -o GitLabUtil.py -s
    - python GitLabUtil.py getfile "22" "deployment.yaml" "master" "deployment.yaml"
    - ls -l
    - imageName=192.168.204.15/${CI_PROJECT_NAMESPACE}/${CI_PROJECT_NAME}:${CI_COMMIT_SHA}
    - sed -i 's#__PORT__#80#g' deployment.yaml
    - sed -i "s#__APPNAME__#${CI_PROJECT_NAME}#g" deployment.yaml
    - sed -i "s#__NAMESPACE__#${CI_PROJECT_NAMESPACE}#g" deployment.yaml
    - sed -i "s#__IMAGENAME__#${imageName}#g" deployment.yaml
    - python GitLabUtil.py updatefile "22" "deployment.yaml" "master" "${CI_PROJECT_NAME}%2f${CI_COMMIT_BRANCH}.yaml"



#sonarscan:
# extends:
# - .sonarscan

#pushartifact:
# extends:
# - .pushartifact

dockerbuild:
  extends:
   - .dockerbuild

(10)共享库完整目录

(11)GitLab 前端项目运行流水线

(12)完成

(13)查看各阶段日志

(14)环境库项目显示更新master.yaml文件

(15) 查看master.yaml文件(已同步更新端口号、命名空间、项目名称及镜像名称)

6.ArgoCD 完成前端项目应用发布

(1)K8S查看集群状态

# kubectl get node

(2)K8S master节点另开一个终端用watch命令观察pod变化

# watch -n 1 "kubectl get pod -n devops03"

(3)外部测试访问

# curl http://devops03-devops-ui.devops.com:31291

(4)K8S 删除命名空间devops03

# kubectl delete ns devops03

(5) 观察pod变化

(5)ArgoCD 查看已有项目

(6)ArgoCD 删除已有项目

 

(7)GitLab环境库注释其他的yaml文件

(8)ArgoCD 创建application (手动策略、自动创建命名空间、指定仓库与集群)

(9)填写配置

(10)完成创建

(11)点击 SYNCHRONIZE (同步)

(12)观察pod变化

(13)ArgoCD 观察pod变化

(14)查看Harbor仓库镜像文件

(15)K8S node节点连接Harbor拉取镜像

# docker login -u admin -p Harbor12345 192.168.204.15
 
# docker pull 192.168.204.15/devops03/devops03-devops-ui:RELEASE-1.1.7
 
# docker logout 192.168.204.15

node1 节点

node2节点

(16)观察pod变化

(17)ArgoCD 再次观察pod变化

(18) 外部测试访问

# curl http://devops03-devops-ui.devops.com:31291

二、问题

1.Python获取GitLab指定仓库文件报错

(1)报错

(2)原因分析

函数名错误

(3)解决方法

修改函数名称。

修改前:

修改后:

2. K8S master节点运行Python代码报错

(1)报错

(2)原因分析

encoding不是有效的关键词。

(3)解决方法

去掉encoding。

修改前:

修改后:

成功:

3. GitLabCI 运行流水线报错

(1)报错

(2)原因分析

行尾缺少双引号

(3)解决方法

添加双引号。

成功:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/264636.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深度剖析Ajax实现方式(原生框架、JQuery、Axios,Fetch)

Ajax学习 简介&#xff1a; ​ Ajax 代表异步 JavaScript 和 XML&#xff08;Asynchronous JavaScript and XML&#xff09;的缩写。它指的是一种在网页开发中使用的技术&#xff0c;通过在后台与服务器进行数据交换&#xff0c;实现页面内容的更新&#xff0c;而无需刷新整个…

Halcon 检测焊点短路

Halcon 检测焊点短路 read_image (Image1, D:/image/bilibili/photo/检测焊接短路 (4).bmp) dev_close_window () dev_open_window (0, 0, 512, 512, black, WindowHandle) dev_display (Image1) set_display_font (WindowHandle, 16, mono, true, false) threshold (Image1, …

kindeditor The method toJSONString() is undefined for the type JSONObject

kindeditor 插件上传文件出错的 json_simple-1.1.jar 也不知道是多老的项目&#xff0c;多老的包了&#xff0c;稀有东西

基于SSM的剧本杀预约系统(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的剧本杀预约系统&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;通过Spring Sp…

日志服务 SLS 深度解析:拥抱云原生和 AI,基于 SLS 的可观测分析创新

云布道师 10 月 31 日&#xff0c;杭州云栖大会上&#xff0c;日志服务 SLS 研发负责人简志和产品经理孟威等人发表了《日志服务 SLS 深度解析&#xff1a;拥抱云原生和 AI&#xff0c;基于 SLS 的可观测分析创新》的主题演讲&#xff0c;对阿里云日志服务 SLS 产品服务创新以…

使用 Elasticsearch 检测抄袭 (一)

作者&#xff1a;Priscilla Parodi 抄袭可以是直接的&#xff0c;涉及复制部分或全部内容&#xff0c;也可以是释义的&#xff0c;即通过更改一些单词或短语来重新表述作者的作品。 灵感和释义之间是有区别的。 即使你得出类似的结论&#xff0c;也可以阅读内容&#xff0c;获得…

罗技鼠标驱动下载地址

罗技鼠标驱动下载地址 Logitech G HUB Advanced Gaming Software, RGB & Game Profiles

Flutter 三: Dart

1 数据类型 数字(number) int double 字符串转换成 num int.parse(“1”) double.parse(“1”);double 四舍五入保留两位小数 toStringAsFixed(2) 返回值为stringdouble 直接舍弃小数点后几位的数据 可使用字符串截取的方式 字符串(string) 单引号 双引号 三引号三引号 可以输…

windos/ubuntu20.4下UE4.27.2像素流送

windows/ubuntu20.4下UE4.27.2像素流送 像素流送技术可以将服务器端打包的虚幻引擎应用程序在客户端的浏览器上运行&#xff0c;用户可以通过浏览器操作虚幻引擎应用程序&#xff0c;客户端无需下载虚幻引擎&#xff0c;本文实现两台机器通过物理介质网线实现虚幻引擎应用程序…

解决xcode 运行不老iPhone 15 iOS 17.1 设备的问题

问题 最近要查看一下ios 17.1的设备的性能&#xff0c;但是当前版本的Xcode运行不了 解决方法 1、更新Xcode版本到15.1以上 2、更新完成后&#xff0c;大概率出现这个情况 原因&#xff1a;在app Store中更新到Xcode15后,运行不了模拟器和真机.需要下载iOS 17对应的模拟器.&…

层次分析法

层次分析法主要用于解决评价类问题(例如选择哪种方案最好&#xff0c;哪位运动员或者员工表现的更优秀) 先用一道引出层次分析法的例题&#xff1a;小明同学高考填完志愿后&#xff0c;小明想出去旅游。在查阅了网上的攻略后&#xff0c;他初步选择了苏杭、北戴河和桂林三地之一…

使用Aspose.Slides 控件,在线将 ODP 转换为 PPT

OpenOffice 等开源生产力工具有其用途。但如果您希望在线将 ODP 转换为 PPT&#xff0c;您很可能已经确定 Microsoft PowerPoint 的专有 PPT 格式和平台比 OpenOffice ODP 更适合您的需求。 本文的第一部分重点介绍在线将 ODP 转换为 PPT 的快速方法。第二部分探讨涉及C#应用程…

Redis设计与实现之AOF

一、AOF Redis 分别提供了 RDB 和 AOF 两种持久化机制: RDB 将数据库的快照(snapshot)以二进制的方式保存到磁盘中。 AOF 则以协议文本的方式&#xff0c;将所有对数据库进行过写入的命令(及其参数)记录到 AOF 文件&#xff0c;以此达到记录数据库状态的目的。 本章首先介绍…

从零开发短视频电商 在AWS上SageMaker部署模型自定义日志输入和输出示例

从零开发短视频电商 在AWS上SageMaker部署模型自定义日志输入和输出示例 怎么部署自定义模型请看&#xff1a;从零开发短视频电商 在AWS上用SageMaker部署自定义模型 都是huaggingface上的模型或者fine-tune后的。 为了适配jumpstart上部署的模型的http输入输出&#xff0c;我…

springMVC-与spring整合

一、基本介绍 在项目开发中&#xff0c;spring管理的 Service和 Respository&#xff0c;SrpingMVC管理 Controller和ControllerAdvice,分工明确 当我们同时配置application.xml, springDispatcherServlet-servlet.xml , 那么注解的对象会被创建两次&#xff0c; 故…

2023 下半年系统架构设计师学习进度

文章目录 复习计划&#xff1a;每周350分钟第一周&#xff08;339分钟&#xff09;第二周&#xff08;265分钟&#xff09;第三周&#xff08;171分钟&#xff09;第四周&#xff08;214分钟&#xff09;第五周&#xff08;274分钟&#xff09;第六周&#xff08;191分钟&#…

初识Stable Diffusion

界面选项解读 这是在趋动云上部署的Stable Diffusion txt2img prompt &#xff08;1&#xff09;分割符号&#xff1a;使用逗号 , 用于分割词缀&#xff0c;且有一定权重排序功能&#xff0c;逗号前权重高&#xff0c;逗号后权重低 &#xff08;2&#xff09;建议的通用范式…

【Java JMM】编译和优化

1 前端编译 在 Java 技术下, “编译期” 是一个比较含糊的表述, 因为它可能指的是 前端编译器 (“编译器的前端” 更准确一些) 把 *.java 文件转变成 *.class 文件的过程Java 虚拟机的即时编译器 (常称 JIT 编译器, Just In Time Compiler) 运行期把字节码转变成本地机器码的过…

《Python》面试常问:深拷贝、浅拷贝、赋值之间的关系(附可变与不可变)【用图文讲清楚!】

背景 想必大家面试或者平时学习经常遇到问python的深拷贝、浅拷贝和赋值之间的区别了吧&#xff1f;看网上的文章很多写的比较抽象&#xff0c;小白接收的难度有点大&#xff0c;于是乎也想自己整个文章出来供参考 可变与不可变 讲深拷贝和浅拷贝之前想讲讲什么是可变数据类型…

Pytorch常用的函数(五)np.meshgrid()和torch.meshgrid()函数解析

Pytorch常用的函数(五)np.meshgrid()和torch.meshgrid()函数解析 我们知道torch.meshgrid()函数的功能是生成网格&#xff0c;可以用于生成坐标&#xff1b; 在numpy中也有一样的函数np.meshgrid()&#xff0c;但是用法不太一样&#xff0c;我们直接上代码进行解释。 1、两者…