• [热门活动] 不仅有干货,还有问题的答案,还在等什么,快来看了 。
     codeArts2月份技术干货合集以及数据库版块问题合集。 1.pytest中的fixture基本用法【转】 https://bbs.huaweicloud.com/forum/thread-0234112932818513063-1-1.html  2.java double 类型_关于Java中的double类型数据【转】 https://bbs.huaweicloud.com/forum/thread-0222111742558810011-1-1.html  3.解决 Maven ‘parent.relativePath‘ of POM【转】 https://bbs.huaweicloud.com/forum/thread-0236112434845316028-1-1.html  4.Non-resolvable parent POM for解决【转】 https://bbs.huaweicloud.com/forum/thread-0220112499223799035-1-1.html  5.在Maven中出现Could not find artifact ...:pom:0.0.1-SNAPSHOT and ‘parent.relativePath‘的错误怎么解决?【转】 https://bbs.huaweicloud.com/forum/thread-0267112499546748034-1-1.html  6.Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean【转】 https://bbs.huaweicloud.com/forum/thread-0221112501396435024-1-1.html  7.Python利用plotly绘制正二十面体详解【转】 https://bbs.huaweicloud.com/forum/thread-0275112930670884059-1-1.html  8.基于Python实现绘制一个足球【转】 https://bbs.huaweicloud.com/forum/thread-0261112931071459060-1-1.html  9.python __init__与 __new__的区别【转】 https://bbs.huaweicloud.com/forum/thread-0234112931373944060-1-1.html  10.详解Flask数据库的连接与使用【转】 https://bbs.huaweicloud.com/forum/thread-0221112931454173048-1-1.html  11.tensorflow1.x和tensorflow2.x中的tensor转换为字符串的实现【转】 https://bbs.huaweicloud.com/forum/thread-0261112931688113061-1-1.html  12.Flask中特殊装饰器的使用【转】 https://bbs.huaweicloud.com/forum/thread-0237112931865991052-1-1.html  13.pytorch 简介及常用工具包展示【转】 https://bbs.huaweicloud.com/forum/thread-0236112932234100050-1-1.html  14.Pytorch中的 torch.distributions库详解【转】 https://bbs.huaweicloud.com/forum/thread-0234112932425200062-1-1.html  数据库版块问题合集 1.【GaussDB】连接高斯数据库建议使用什么工具? https://bbs.huaweicloud.com/forum/thread-0220111983015871012-1-1.html  2.【GaussDB】数据库存入空字符串会全部被转成NULL,这个能控制不转吗? https://bbs.huaweicloud.com/forum/thread-0236111894276100005-1-1.html  3.【GaussDB】 GaussDB create sequence有if not exists 的类似写法吗 https://bbs.huaweicloud.com/forum/thread-0237111825559668004-1-1.html  4.【GaussDB】连接高斯数据库建议使用什么工具? https://bbs.huaweicloud.com/forum/thread-0220111983015871012-1-1.html  5.【GaussDB】报错: "ERROR:query returened no rows when process into context",怎么处理? https://bbs.huaweicloud.com/forum/thread-0261111825433614001-1-1.html  
  • [技术干货] pytest中的fixture基本用法【转】
    简介:  fixture区别于unnitest的传统单元测试(setup/teardown)有显著改进:  1.有独立的命名,并通过声明它们从测试函数、模块、类或整个项目中的使用来激活。  2.按模块化的方式实现,每个fixture都可以互相调用。  3.fixture的范围从简单的单元测试到复杂的功能测试,可以对fixture配置参数,或者跨函数function,类class,模块module或整个测试session范围。fixture的功能fixture是pytest特有的功能,用以在测试执行前和执行后进行必要的准备和清理工作。使用pytest.fixture标识,定义在函数前面。在你编写测试函数的时候,你可以将此函数名称做为传入参数,pytest将会以依赖注入方式,将该函数的返回值作为测试函数的传入参数。主要的目的是为了提供一种可靠和可重复性的手段去运行那些最基本的测试内容。从功能上看来,与setup、teardown相似,但是优势明显:命名方式灵活,不局限于setup和teardown这几个命名conftest.py 配置里可以实现数据共享,不需要import就能自动找到一些配置scope="module" 每一个.py文件调用一次scope="session" 可以实现多个.py跨文件使用一个session来完成多个用例特点及优势1、命令灵活:对于setup.teardown,可以不起这两个名字2、数据共享:在conftest.py配置里写的方法可以实现数据共享,不需要import导入,可以跨文件共享3、scope的层次及神奇的yield组合相当于各种setup和teardown4、实现参数化基本用法@pytest.fixture()import pytest @pytest.fixture() def login():     print("完成登录操作") def test_search():     print("搜索功能,此方法不需要完成登录即可执行") def test_cart(login):     print("加入购物车,需要完成登录才可以")fixture在自动化中的应用--作用域@pytest.fixture(scope='module')取值范围说明function函数级每个函数或方法都会调用class类级别每个测试类只运行一次module模块级别每一个.py文件只调用一次package包级没一个python包至调用一次session会话级每次会话只需要运行一次,会话内所有方法及类、模块都共享这个方法import pytest @pytest.fixture(scope='module') def login():     print("完成登录操作") def test_search(login):     print("搜索功能,此方法不需要完成登录即可执行") def test_cart(login):     print("加入购物车,需要完成登录才可以")、fixture在自动化中的应用-yield关键字场景:你已经可以将测试方法【前要执行的或依赖的】解决了,测试方法后销毁清除数据的要如何进行呢?解决:通过在fixture函数中加入yield关键字,yield是调用第一次返回结果,第二次执行他下面的语句返回。步骤:在@pytest.fixture(scope=module),在登录的方法中加yield,之后加销毁清楚的步骤。import pytest @pytest.fixture(scope='module') def login():     # setup操作     print("完成登录操作")     token = 1     yield token  # 相当于return的操作     # teardown操作     print("完成登出操作")   def test_search(login):     # print("搜索功能,此方法不需要完成登录即可执行")     print(f"token = {login}")   def test_cart(login):     # print("加入购物车,需要完成登录才可以")     print(f"token = {login}")fixture在自动化中的应用--数据共享场景:与其他测试工程师合作一起开发时,公共的模块要在不同的文件中,要在大家都能访问到的地方解决:使用conftest.py这个文件进行数据共享,并且他可以放在不同位置骑着不同的范围共享作用前提:conftest文件名是不能换的放在项目下是全局的数据共享的地方执行:系统执行到参数login时,先从本模块中查找是否有这个名字的变量之后在conftest.py中找是否有步骤:将登录模块带@pytest.fixture写在conftest.py中fixture在自动化中的应用-自动应用场景:不想原测试方法有任何改动,或全部都自动实现自动应用,没特例,也都不需要返回值时可以选择自动应用解决:使用fixture中参数autouse=True实现步骤:在方法上面加@pytest.fixture(autouse=True)fixture在自动化中的应用-参数化场景:测试离不开数据,为了数据灵活,一般数据都是用过参数传的解决:fixture通过固定参数requests传递步骤:在fixture中增加@pytest.fixture(params=[1,2,3,'tom'])在方法参数写request,方法体里面使用request.param接收参数import pytest @pytest.fixture(params=[1, 2, 3, "测试"]) def login(request):     print(f"数据名称为:{request.param}")     return request.param def test_search(login):     print(f"{login}")
  • [技术干货] Pytorch中的 torch.distributions库详解【转】
    Pytorch torch.distributions库包介绍torch.distributions包包含可参数化的概率分布和采样函数。 这允许构建用于优化的随机计算图和随机梯度估计器。不可能通过随机样本直接反向传播。 但是,有两种主要方法可以创建可以反向传播的代理函数。这些是评分函数估计量 score function estimato似然比估计量 likelihood ratio estimatorREINFORCE路径导数估计量 pathwise derivative estimatorREINFORCE 通常被视为强化学习中策略梯度方法的基础,路径导数估计器常见于变分自编码器的重新参数化技巧中。虽然评分函数只需要样本 f(x)的值,但路径导数需要导数 f'(x)。本文重点讲解Pytorch中的 torch.distributions库。pytorch 的 torch.distributions 中可以定义正态分布:import torch from torch.distributions import  Normal mean=torch.Tensor([0,2]) normal=Normal(mean,1)sample()就是直接在定义的正太分布(均值为mean,标准差std是1)上采样:result = normal.sample() print("sample():",result)输出:sample(): tensor([-1.3362,  3.1730])rsample()不是在定义的正太分布上采样,而是先对标准正太分布 N(0,1) 进行采样,然后输出: mean + std × 采样值result = normal.rsample() print("rsample():",result)输出:rsample: tensor([ 0.0530,  2.8396])log_prob(value) 是计算value在定义的正态分布(mean,1)中对应的概率的对数,正太分布概率密度函数是:对其取对数可得:这里我们通过对数概率还原其对应的真实概率:print("result log_prob:",normal.log_prob(result).exp())输出:result log_prob: tensor([ 0.1634,  0.2005])
  • [技术干货] pytorch 简介及常用工具包展示【转】
    一、pytorch 简介Pytorch是torch的python版本,是由Facebook开源的神经网络框架,专门针对 GPU 加速的深度神经网络(DNN)编程。Torch 是一个经典的对多维矩阵数据进行操作的张量(tensor )库,在机器学习和其他数学密集型应用有广泛应用。Pytorch的计算图是动态的,可以根据计算需要实时改变计算图。由于Torch语言采用 Lua,导致在国内一直很小众,并逐渐被支持 Python 的 Tensorflow 抢走用户。作为经典机器学习库 Torch 的端口,PyTorch 为 Python 语言使用者提供了舒适的写代码选择。二、pytorch 优势1.简洁:PyTorch的设计追求最少的封装,尽量避免重复造轮子。不像 TensorFlow 中充斥着session、graph、operation、name_scope、variable、tensor、layer等全新的概念,PyTorch 的设计遵循tensor→variable(autograd)→nn.Module 三个由低到高的抽象层次,分别代表高维数组(张量)、自动求导(变量)和神经网络(层/模块),而且这三个抽象之间联系紧密,可以同时进行修改和操作。2.速度:PyTorch 的灵活性不以速度为代价,在许多评测中,PyTorch 的速度表现胜过 TensorFlow和Keras 等框架。3.易用:PyTorch 是所有的框架中面向对象设计的最优雅的一个。PyTorch的面向对象的接口设计来源于Torch,而Torch的接口设计以灵活易用而著称,Keras作者最初就是受Torch的启发才开发了Keras。4.活跃的社区:PyTorch 提供了完整的文档,循序渐进的指南,作者亲自维护的论坛,供用户交流和求教问题。Facebook 人工智能研究院对 PyTorch 提供了强力支持。三、pytorch 常用工具包torch :类似 NumPy 的张量库,支持GPU;torch.autograd :基于 type 的自动区别库,支持 torch 之中的所有可区分张量运行;torch.nn :为最大化灵活性而设计,与 autograd 深度整合的神经网络库;torch.optim:与 torch.nn 一起使用的优化包,包含 SGD、RMSProp、LBFGS、Adam 等标准优化方式;torch.multiprocessing: python 多进程并发,进程之间 torch Tensors 的内存共享;torch.utils:数据载入器。具有训练器和其他便利功能;torch.legacy(.nn/.optim) :出于向后兼容性考虑,从 Torch 移植来的 legacy 代码;四、pytorch 注意点特别注意一个问题:通道问题:不同视觉库对于图像读取的方式不一样,图像通道也不一样:opencv 的 imread 默认顺序时 H * W * Cpytorch的Tensor是 C * H * WTensorflow是两者都支持五、pytorch 理解numpy风格的tensor操作pytorch对tensor提供的API参照了numpy变量自动求导在计算过程形成的计算图中,参与的变量可快速计算出自己对于目标函数的梯度神经网络求导及损失函数优化等高层封装网络层封装在torch.nn损失函数封装在torch.functional优化函数封装在torch.optim六、pytorch-Tensor1. tensor 数据类型tensor数据类型:3浮点(float16,float32,float64)5整数(int16,int32,int64,int8+uint8)Data typedtypeCPU tensorGPU tensor16-bit floating pointtorch.float16 or torch.halftorch.HalfTensortorch.cuda.HalfTensor32-bit floating pointtorch.float32 or torch.floattorch.FloatTensortorch.cuda.FloatTensor64-bit floating pointtorch.float64 or torch.doubletorch.DoubleTensortorch.cuda.DoubleTensorData typedtypeCPU tensorGPU tensor8-bit integer(unsigned)torch.uint8torch.ByteTensortorch.cuda.ByteTensor8-bit integer(signed)torch.int8torch.CharTensortorch.cuda.CharTensor16-bit integer(signed)torch.int16 or torch.shorttorch.ShortTensortorch.cuda.ShortTensor32-bit integer(signed)torch.int32 or torch.inttorch.IntTensortorch.cuda.IntTensor64-bit integer(signed)torch.int64 or torch.longtorch.LongTensortorch.cuda.LongTensor2. 创建 tensor 相关的 API创建tensor的常见api方法名说明Tensor()直接从参数构造张量,支持list和numpy数组eye(row,column)创建指定行数&列数的单位tensor(单位阵)linspace(start,end,count)在[s,e]上创建c个元素的一维tensorlogspace(start,end,count)在[10s,10e]上创建c个元素的一维tensorones(size)返回指定shape的tensor,元素初始值为1zeros(size)返回指定shape的tensor,元素初始值为0ones_like(t)返回一个tensor,shape与t相同,且元素初始值为1zeros_like(t)返回一个tensor,shape与t相同,且元素初始值为1arange(s,e,sep)在区间[s,e)上以间隔sep生成一个序列张量3. tensor 对象的 APItensor 对象的方法方法名作用size()返回张量的shapenumel()计算tensor的元素个数view(shape)修改tensor的shape,与np.reshape相似,view返回的是对象的共享内存resize类似于view,但在size超出时会重新分配内存空间item若为单元素tensor,则返回python的scalarfrom_numpy从numpy数据填充numpy返回ndarray类型七、python 自动求导tensor对象通过一系列运算组成动态图,每个tensor对象都有以下几个控制求导的属性。变量作用requird_grad默认为False,表示变量是狗需要计算导数grad_fn变量的梯度函数grad变量对应的梯度八、pytorch 神经网络torch.nn提供了创建神经网络的基础构件,这些层都继承自Module类。下面是自己手动实现一个线性层(linear layer)。适当参考,以后直接调用现成的接口,这里稍微了解一下,无实际意义。 import torch  class Linear(torch.nn.Module):     def __init__(self, in_features, out_features, bias=True):         super(Linear, self).__init__()         # torch.randn() 返回一个符合均值为0,方差为1的正态分布         self.weight = torch.nn.Parameter(torch.randn(out_features, in_features))         if bias:             self.bias = torch.nn.Parameter(torch.randn(out_features))      def forward(self, x):         # xW+b         x = x.mm(self.weight)         if self.bias:             x = x + self.bias.expand_as(x)         return x  if __name__ == '__main__':          net = Linear(3,2)     x = net.forward     print('11',x) 下面表格中列出了比较重要的神经网络层组件。对应的在nn.functional模块中,提供这些层对应的函数实现。通常对于可训练参数的层使用module,而对于不需要训练参数的层如softmax这些,可以使用functional中的函数。一些容器:容器类型功能Module神经网络模块基类Sequential序贯模型,类似keras,用于构建序列型神经网络ModuleList用于存储层,不接受输入Parameters(t)模块的属性,用于保存其训练参数ParameterList参数列表1容器代码: # 方法1 像 model1 = nn.Sequential() model.add_module('fc1', nn.Linear(3,4)) model.add_module('fc2', nn.Linear(4,2)) model.add_module('output', nn.Softmax(2))  # 方法2 model2 = nn.Sequential(           nn.Conv2d(1,20,5),           nn.ReLU(),           nn.Conv2d(20,64,5),           nn.ReLU()         ) # 方法3         model3 = nn.ModuleList([nn.Linear(3,4), nn.ReLU(), nn.Linear(4,2)]) torch.nn.Module提供了神经网络的基类,当实现神经网络时需要继承自此模块,并在初始化函数中创建网络需要包含的层,并实现forward函数完成前向计算,网络的反向计算会由自动求导机制处理。通常将需要训练的层写在init函数中,将参数不需要训练的层在forward方法里调用对应的函数来实现相应的层。编码三步走:在pytorch中就只需要分三步:写好网络;编写数据的标签和路径索引;把数据送到网络。
  • [技术干货] Flask中特殊装饰器的使用【转】
    (1)@app.before_request请求到达视图函数之前,进行自定义操作,类似django中间件中的process_request,在app中使用则为全局,在蓝图中使用则针对当前蓝图注意正常状态下return值必须为None(2)@app.after_request响应返回到达客户端之前,进行自定义操作,类似jango中间件中的process_response,在app中使用则为全局,在蓝图中使用则针对当前蓝图注意正常状态下视图函数必须定义一个形参接收response对象,并通过return response返回(3)@app.errorhandler()错误状态码捕获执行函数,装饰器参数务必是4xx或者5xx的int型错误状态码(4) @app.template_global() :定义装饰全局模板可用的函数,直接可在模板中进行渲染使用@app.template_filter(): 定义装饰全局模板可用的过滤器函数,类似django中的自定义过滤器,直接可在模板中使用这两个特殊装饰器主要用在模板渲染!!!import apps from flask import request, session, redirect   app = apps.create_app()    @app.before_request def before1():     print("before1", request)    @app.before_request def before2():     print("before2")     if request.path == "/":         return None     else:         #这里抛出了一个异常,会被@app.errorhandler(Exception)         # 捕获到。         raise Exception("hahaha")    @app.before_request def before3():     print("before3")    @app.after_request def after1(res):     print("after1")     return res    @app.after_request def after2(res):     print("after2")     return res    @app.after_request def after3(res):     print("after3")     return res    # 处理异常,接受参数,可以重定向到指定页面 @app.errorhandler(Exception) def error(e):     print("error")     return redirect("/")    @app.route("/login") def login():     print("login")     return "login"   @app.route('/') def hello_world():  # put application's code here     return 'Hello World!'   if __name__ == '__main__':     app.run()
  • [技术干货] tensorflow1.x和tensorflow2.x中的tensor转换为字符串的实现【转】
    Tensorflow1.xTensorFlow 1.x 和 TensorFlow 2.x 的 API 存在很大差异,如果您想要将 TensorFlow 1.x 中的 tensor 格式转换成字符串,可以按照以下步骤进行:导入 TensorFlow 1.x 和其他必要的 Python 库。import tensorflow.compat.v1 as tf import numpy as np定义一个 TensorFlow 1.x 的 Tensor。例如:x = tf.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.float32) 使用 tf.as_string() 方法将 Tensor 转换为字符串。例如:str_tensor = tf.as_string(x) 在 TensorFlow 1.x 中,Tensor 对象可以在 Session 中运行以获得实际的值。因此,在使用上述方法将 Tensor 转换为字符串后,需要在 Session 中运行以获得字符串值。with tf.Session() as sess:     str_tensor = sess.run(str_tensor) 在上面的例子中,我们使用了 TensorFlow 1.x 的 Session 来运行字符串 Tensor,最后 str_tensor 变量将包含 Tensor 的字符串表示形式。需要注意的是,在 TensorFlow 2.x 中,tf.as_string() 方法已经被 tf.strings.as_string() 方法所替代。同时,TensorFlow 2.x 中不需要使用 Session 来运行 Tensor 对象。Tensorflow2.x要将TensorFlow的Tensor格式转换为字符串,可以使用TensorFlow中的tf.strings方法。具体步骤如下:导入TensorFlow和其他必要的Python库。import tensorflow as tf import numpy as np 定义一个TensorFlow Tensor。例如:x = tf.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.float32) 使用tf.strings.format()方法将Tensor转换为字符串。可以使用format()方法的模板字符串,将Tensor中的元素插入到字符串中。例如:str_tensor = tf.strings.format("Tensor: {}", x) 在上面的例子中,我们使用了"Tensor: {}"字符串作为模板,其中{}将被Tensor x中的元素替换。使用.numpy()方法将字符串Tensor转换为普通的Python字符串。例如:str_tensor = str_tensor.numpy().decode('utf-8') 在上面的例子中,我们首先使用.numpy()方法将Tensor转换为Numpy数组,然后使用.decode()方法将数组转换为UTF-8编码的字符串。最后,str_tensor变量将包含Tensor的字符串表示形式。
  • [技术干货] 详解Flask数据库的连接与使用【转】
    数据库连接配置HOST = "XXXXXXXXXXXXX" PORT = 3310 USERNAME = "root" PASSWORD = "@XXXXXXXXXXX" DATABASE = "mydb"   SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{USERNAME}:{quote(PASSWORD)}@{HOST}:{PORT}/{DATABASE}?charset=utf8mb4" SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_ECHO = True 创建实体类from exts.DBServer import db from sqlalchemy import Column, Integer, String, Date, DateTime     class Article(db.Model):     __tablename__ = "article"     id = Column(Integer, primay_key=True, autoincrement=True)     title = Column(String(100), nullable=True)     pub_time = Column(DateTime, nullable=True)     author = Column(String(100), nullable=True)     content = Column(String(10000), nullable=True)     origin = Column(String(1000), nullable=True) controller:import json   from flask.blueprints import Blueprint from exts.DBServer import db from ..model.Article import Article from flask_sqlalchemy.query import Query from flask_restful import marshal from flask_restful import fields   article_bp = Blueprint("article", __name__, url_prefix="/article")   article_fields = {     "id": fields.Integer,     "title": fields.String,     "pub_time": fields.DateTime,     "author": fields.String,     "content": fields.String,     "origin": fields.String }     @article_bp.route("/queryAll") def queryAll():     query: Query = Article.query     articles = query.all()     article = query.get(1)     article2 = query.filter_by(author="XXX")     return json.dumps(marshal(articles, fields=article_fields),ensure_ascii=False) 配置打印SQL语句from exts.DBServer import db from sqlalchemy import Column, Integer, String     class User(db.Model):     __tablename__ = "user"     id = Column(Integer, primary_key=True, autoincrement=True)     username = Column(String(100), nullable=True)     password = Column(String(100), nullable=True)       def __repr__(self):         return "User %r" % self.body 或、与、非和排序@user_bp.route("/query") def query_match():     query: Query = User.query     result = query.filter(or_(User.username.contains("祥"), User.id == 1))       return json.dumps(marshal(result.all(), fields=user_fields), ensure_ascii=False)     @user_bp.route("/in") def in_sql():     query: Query = User.query     result = query.order_by(-User.password, -User.id)     return json.dumps(marshal(result.all(), fields=user_fields), ensure_ascii=False)
  • [技术干货] python __init__与 __new__的区别【转】
    一、构造函数 __init__ 与__new____new__   作用: 创建对象,并分配内存__init__ 作用: 初始化对象的值注意:1、与java相比,java只有一个构造器。而python  __new__  方法与 __init__ 方法 组合,才能称为一个对应类似于java中的构造器 2、先执行__new__ ,创建对象,并分配内存.再执行 __init__,初始化对象的值。3、任何类都继承于object 类。我们一般不重写__new__ 方法。 我们不重写,就默认调用父类 的 __new__ 方法。4、__new__ 方法 ,一定要return 一个对象。 如果自己重写__new__ 方法,但是没有return出一个对象。连对象都没创建成功,后面是不会进行初始化对象的。例子1:class Person(object):     def __init__(self,name,id,sex):         self.name = name         self.id = id         self.sex = sex         print("初始化对象的值")       def __new__(cls, *args, **kwargs):         print("开始创建对象,并分配内存")   if __name__ == '__main__':     p = Person("张三",12,"男") 运行结果,只执行了__new__ 方法,并没有执行 __init__方法。为啥呢? 因为new函数,没有返回一个 对象。正确的用法class Person(object):     def __init__(self,name,id,sex):         self.name = name         self.id = id         self.sex = sex         print("初始化对象的值")       def __new__(cls, *args, **kwargs):         print("开始创建对象,并分配内存")         self = super().__new__(cls)         return self   if __name__ == '__main__':     p = Person("张三",12,"男")打印结果:开始创建对象,并分配内存初始化对象的值
  • [技术干货] 基于Python实现绘制一个足球【转】
    如果想优雅地绘制一个足球,那首先需要绘制正二十面体 https://bbs.huaweicloud.com/forum/thread-0275112930670884059-1-1.html import numpy as np from itertools import product G = (np.sqrt(5)-1)/2 def getVertex():     pt2 =  [(a,b) for a,b in product([1,-1], [G, -G])]     pts =  [(a,b,0) for a,b in pt2]     pts += [(0,a,b) for a,b in pt2]     pts += [(b,0,a) for a,b in pt2]     return np.array(pts)  def getDisMat(pts):     N = len(pts)     dMat = np.ones([N,N])*np.inf     for i in range(N):         for j in range(i):             dMat[i,j] = np.linalg.norm([pts[i]-pts[j]])     return dMat  pts = getVertex() dMat = getDisMat(pts) # 由于存在舍入误差,所以得到的边的数值可能不唯一 ix, jx = np.where((dMat-np.min(dMat))<0.01) # 获取正二十面体的边 edges = [pts[[i,j]] for i,j in zip(ix, jx)] def isFace(e1, e2, e3):     pts = np.vstack([e1, e2, e3])     pts = np.unique(pts, axis=0)     return len(pts)==3  from itertools import combinations # 获取正二十面体的面 faces = [es for es in combinations(edges, 3)      if isFace(*es)] 为了克服plot_trisurf在xy坐标系中的bug,需要对足球做一点旋转,所以下面要写入旋转矩阵。 # 将角度转弧度后再求余弦 cos = lambda th : np.cos(np.deg2rad(th)) sin = lambda th : np.sin(np.deg2rad(th))  # 即 Rx(th) => Matrix Rx = lambda th : np.array([     [1, 0,       0],     [0, cos(th), -sin(th)],     [0, sin(th), cos(th)]]) Ry = lambda th : np.array([     [cos(th),  0, sin(th)],     [0      ,  1, 0],     [-sin(th), 0, cos(th)] ]) Rz = lambda th : np.array([     [cos(th) , sin(th), 0],     [-sin(th), cos(th), 0],     [0       , 0,       1]]) 先画六边形足球其实就是正二十面体削掉顶点,正二十面体有20个面和12个顶点,每个面都是三角形。削掉顶点对于三角形而言就是削掉三个角,如果恰好选择在1/3的位置削角,则三角形就变成正六边形;而每个顶点处刚好有5条棱,顶点削去之后就变成了正五边形。而正好足球的六边形和五边形有着不同的颜色,所以可以分步绘制,先来搞定六边形。由于此前已经得到了正二十面体的所有面,同时还有这个面对应的所有边,故而只需在每一条边的1/3 和2/3处截断,就可以得到足球的正六边形。 def getHexEdges(face):     pts = []     for st,ed in face:         pts.append((2*st+ed)/3)         pts.append((st+2*ed)/3)     return np.vstack(pts)  ax = plt.subplot(projection='3d') for f in faces:     pt = getHexEdges(f)     pt = Rx(1)@Ry(1)@pt.T     ax.plot_trisurf(*pt, color="white") 再画五边形接下来要做的是,将五边形的窟窿补上,正如一开始说的,这个五边形可以理解为削去顶点而得到的,所以第一件事,就是要找到一个顶点周围的所有边。具体方法就是,对每一个顶点遍历所有边,如果某条边中存在这个顶点,那么就把这个边纳入到这个顶点的连接边。 def getPtEdges(pts, edges):     N = len(pts)     pEdge = [[] for pt in pts]     for i,e in product(range(N),edges):         if (pts[i] == e[0]).all():              pt = (2*pts[i]+e[1])/3         elif (pts[i] == e[1]).all():              pt = (2*pts[i]+e[0])/3         else:             continue         pEdge[i].append(pt)     return np.array(pEdge)  pEdge = getPtEdges(pts, edges) 接下来,就可以绘制足球了 ax = plt.subplot(projection='3d') for f in faces:     pt = getHexEdges(f)     pt = Rx(1)@Ry(1)@pt.T     ax.plot_trisurf(*pt, color="white")  for pt in pEdge:     pt = Rx(1)@Ry(1)@pt.T     ax.plot_trisurf(*pt, color="black")  plt.show() 
  • [技术干货] 图片去摩尔纹简述实现python代码示例【转】
    当感光元件像素的空间频率与影像中条纹的空间频率接近时,可能产生一种新的波浪形的干扰图案,即所谓的摩尔纹。传感器的网格状纹理构成了一个这样的图案。当图案中的细条状结构与传感器的结构以小角度交叉时,这种效应也会在图像中产生明显的干扰。这种现象在一些细密纹理情况下,比如时尚摄影中的布料上,非常普遍。这种摩尔纹可能通过亮度也可能通过颜色来展现。但是在这里,仅针对在翻拍过程中产生的图像摩尔纹进行处理。翻拍即从计算机屏幕上捕获图片,或对着屏幕拍摄图片;该方式会在图片上产生摩尔纹现象论文主要处理思路对原图作Haar变换得到四个下采样特征图(原图下二采样cA、Horizontal横向高频cH、Vertical纵向高频cV、Diagonal斜向高频cD)然后分别利用四个独立的CNN对四个下采样特征图卷积池化,提取特征信息原文随后对三个高频信息卷积池化后的结果的每个channel、每个像素点比对,取max将上一步得到的结果和cA卷积池化后的结果作笛卡尔积网络结构复现  如下图所示,本项目复现了论文的图像去摩尔纹方法,并对数据处理部分进行了修改,并且网络结构上也参考了源码中的结构,对图片产生四个下采样特征图,而不是论文中的三个,具体处理方式大家可以参考一下网络结构。import math import paddle import paddle.nn as nn import paddle.nn.functional as F # import pywt from paddle.nn import Linear, Dropout, ReLU from paddle.nn import Conv2D, MaxPool2D class mcnn(nn.Layer):     def __init__(self, num_classes=1000):         super(mcnn, self).__init__()         self.num_classes = num_classes         self._conv1_LL = Conv2D(3,32,7,stride=2,padding=1,)               # self.bn1_LL = nn.BatchNorm2D(128)         self._conv1_LH = Conv2D(3,32,7,stride=2,padding=1,)           # self.bn1_LH = nn.BatchNorm2D(256)         self._conv1_HL = Conv2D(3,32,7,stride=2,padding=1,)         # self.bn1_HL = nn.BatchNorm2D(512)         self._conv1_HH = Conv2D(3,32,7,stride=2,padding=1,)         # self.bn1_HH = nn.BatchNorm2D(256)         self.pool_1_LL = nn.MaxPool2D(kernel_size=2,stride=2, padding=0)         self.pool_1_LH = nn.MaxPool2D(kernel_size=2,stride=2, padding=0)         self.pool_1_HL = nn.MaxPool2D(kernel_size=2,stride=2, padding=0)         self.pool_1_HH = nn.MaxPool2D(kernel_size=2,stride=2, padding=0)         self._conv2 = Conv2D(32,16,3,stride=2,padding=1,)         self.pool_2 = nn.MaxPool2D(kernel_size=2,stride=2, padding=0)         self.dropout2 = Dropout(p=0.5)         self._conv3 = Conv2D(16,32,3,stride=2,padding=1,)         self.pool_3 = nn.MaxPool2D(kernel_size=2,stride=2, padding=0)         self._conv4 = Conv2D(32,32,3,stride=2,padding=1,)         self.pool_4 = nn.MaxPool2D(kernel_size=2,stride=2, padding=0)         self.dropout4 = Dropout(p=0.5)         # self.bn1_HH = nn.BatchNorm1D(256)         self._fc1 = Linear(in_features=64,out_features=num_classes)         self.dropout5 = Dropout(p=0.5)         self._fc2 = Linear(in_features=2,out_features=num_classes)     def forward(self, inputs1, inputs2, inputs3, inputs4):         x1_LL = self._conv1_LL(inputs1)         x1_LL = F.relu(x1_LL)         x1_LH = self._conv1_LH(inputs2)         x1_LH = F.relu(x1_LH)         x1_HL = self._conv1_HL(inputs3)         x1_HL = F.relu(x1_HL)         x1_HH = self._conv1_HH(inputs4)         x1_HH = F.relu(x1_HH)         pool_x1_LL = self.pool_1_LL(x1_LL)         pool_x1_LH = self.pool_1_LH(x1_LH)         pool_x1_HL = self.pool_1_HL(x1_HL)         pool_x1_HH = self.pool_1_HH(x1_HH)         temp = paddle.maximum(pool_x1_LH, pool_x1_HL)         avg_LH_HL_HH = paddle.maximum(temp, pool_x1_HH)         inp_merged = paddle.multiply(pool_x1_LL, avg_LH_HL_HH)         x2 = self._conv2(inp_merged)         x2 = F.relu(x2)         x2 = self.pool_2(x2)         x2 = self.dropout2(x2)         x3 = self._conv3(x2)         x3 = F.relu(x3)         x3 = self.pool_3(x3)         x4 = self._conv4(x3)         x4 = F.relu(x4)         x4 = self.pool_4(x4)         x4 = self.dropout4(x4)         x4 = paddle.flatten(x4, start_axis=1, stop_axis=-1)         x5 = self._fc1(x4)         x5 = self.dropout5(x5)         out = self._fc2(x5)         return out model_res = mcnn(num_classes=2) paddle.summary(model_res,[(1,3,512,384),(1,3,512,384),(1,3,512,384),(1,3,512,384)]) ---------------------------------------------------------------------------  Layer (type)       Input Shape          Output Shape         Param #     ===========================================================================    Conv2D-1      [[1, 3, 512, 384]]   [1, 32, 254, 190]        4,736         Conv2D-2      [[1, 3, 512, 384]]   [1, 32, 254, 190]        4,736         Conv2D-3      [[1, 3, 512, 384]]   [1, 32, 254, 190]        4,736         Conv2D-4      [[1, 3, 512, 384]]   [1, 32, 254, 190]        4,736        MaxPool2D-1   [[1, 32, 254, 190]]    [1, 32, 127, 95]          0          MaxPool2D-2   [[1, 32, 254, 190]]    [1, 32, 127, 95]          0          MaxPool2D-3   [[1, 32, 254, 190]]    [1, 32, 127, 95]          0          MaxPool2D-4   [[1, 32, 254, 190]]    [1, 32, 127, 95]          0           Conv2D-5      [[1, 32, 127, 95]]    [1, 16, 64, 48]         4,624        MaxPool2D-5    [[1, 16, 64, 48]]     [1, 16, 32, 24]           0           Dropout-1     [[1, 16, 32, 24]]     [1, 16, 32, 24]           0           Conv2D-6      [[1, 16, 32, 24]]     [1, 32, 16, 12]         4,640        MaxPool2D-6    [[1, 32, 16, 12]]      [1, 32, 8, 6]            0           Conv2D-7       [[1, 32, 8, 6]]       [1, 32, 4, 3]          9,248        MaxPool2D-7     [[1, 32, 4, 3]]       [1, 32, 2, 1]            0           Dropout-2      [[1, 32, 2, 1]]       [1, 32, 2, 1]            0           Linear-1          [[1, 64]]              [1, 2]              130          Dropout-3          [[1, 2]]              [1, 2]               0           Linear-2           [[1, 2]]              [1, 2]               6        =========================================================================== Total params: 37,592 Trainable params: 37,592 Non-trainable params: 0 --------------------------------------------------------------------------- Input size (MB): 9.00 Forward/backward pass size (MB): 59.54 Params size (MB): 0.14 Estimated Total Size (MB): 68.68 --------------------------------------------------------------------------- {'total_params': 37592, 'trainable_params': 37592} 数据预处理  与源代码不同的是,本项目将图像的小波分解部分集成在了数据读取部分,即改为了线上进行小波分解,而不是源代码中的线下进行小波分解并且保存图片。首先,定义小波分解的函数!pip install PyWavelets import numpy as np import pywt def splitFreqBands(img, levRows, levCols):     halfRow = int(levRows/2)     halfCol = int(levCols/2)     LL = img[0:halfRow, 0:halfCol]     LH = img[0:halfRow, halfCol:levCols]     HL = img[halfRow:levRows, 0:halfCol]     HH = img[halfRow:levRows, halfCol:levCols]     return LL, LH, HL, HH def haarDWT1D(data, length):     avg0 = 0.5;     avg1 = 0.5;     dif0 = 0.5;     dif1 = -0.5;     temp = np.empty_like(data)     # temp = temp.astype(float)     temp = temp.astype(np.uint8)     h = int(length/2)     for i in range(h):         k = i*2         temp[i] = data[k] * avg0 + data[k + 1] * avg1;         temp[i + h] = data[k] * dif0 + data[k + 1] * dif1;     data[:] = temp # computes the homography coefficients for PIL.Image.transform using point correspondences def fwdHaarDWT2D(img):     img = np.array(img)     levRows = img.shape[0];     levCols = img.shape[1];     # img = img.astype(float)     img = img.astype(np.uint8)     for i in range(levRows):         row = img[i,:]         haarDWT1D(row, levCols)         img[i,:] = row     for j in range(levCols):         col = img[:,j]         haarDWT1D(col, levRows)         img[:,j] = col     return splitFreqBands(img, levRows, levCols) !cd "data/data188843/" &amp;&amp; unzip -q 'total_images.zip' import os  recapture_keys = [ 'ValidationMoire'] original_keys = ['ValidationClear'] def get_image_label_from_folder_name(folder_name):     """     :param folder_name:     :return:     """     for key in original_keys:         if key in folder_name:             return 'original'     for key in recapture_keys:         if key in folder_name:             return 'recapture'     return 'unclear' label_name2label_id = {     'original': 0,     'recapture': 1,} src_image_dir = "data/data188843/total_images" dst_file = "data/data188843/total_images/train.txt" image_folder = [file for file in os.listdir(src_image_dir)] print(image_folder) image_anno_list = [] for folder in image_folder:     label_name = get_image_label_from_folder_name(folder)     # label_id = label_name2label_id.get(label_name, 0)     label_id = label_name2label_id[label_name]     folder_path = os.path.join(src_image_dir, folder)     image_file_list = [file for file in os.listdir(folder_path) if                         file.endswith('.jpg') or file.endswith('.jpeg') or                         file.endswith('.JPG') or file.endswith('.JPEG') or file.endswith('.png')]     for image_file in image_file_list:         # if need_root_dir:         #     image_path = os.path.join(folder_path, image_file)         # else:         image_path = image_file         image_anno_list.append(folder +"/"+image_path +"\t"+ str(label_id) + '\n') dst_path = os.path.dirname(src_image_dir) if not os.path.exists(dst_path):     os.makedirs(dst_path) with open(dst_file, 'w') as fd:     fd.writelines(image_anno_list) import paddle import numpy as np import pandas as pd import PIL.Image as Image from paddle.vision import transforms # from haar2D import fwdHaarDWT2D paddle.disable_static() # 定义数据预处理 data_transforms = transforms.Compose([     transforms.Resize(size=(448,448)),     transforms.ToTensor(), # transpose操作 + (img / 255)     # transforms.Normalize(      # 减均值 除标准差     #     mean=[0.31169346, 0.25506335, 0.12432463],             #     std=[0.34042713, 0.29819837, 0.1375536])     #计算过程:output[channel] = (input[channel] - mean[channel]) / std[channel] ]) # 构建Dataset class MyDataset(paddle.io.Dataset):     """     步骤一:继承paddle.io.Dataset类     """     def __init__(self, train_img_list, val_img_list, train_label_list, val_label_list, mode='train', ):         """         步骤二:实现构造函数,定义数据读取方式,划分训练和测试数据集         """         super(MyDataset, self).__init__()         self.img = []         self.label = []         # 借助pandas读csv的库         self.train_images = train_img_list         self.test_images = val_img_list         self.train_label = train_label_list         self.test_label = val_label_list         if mode == 'train':             # 读train_images的数据             for img,la in zip(self.train_images, self.train_label):                 self.img.append('/home/aistudio/data/data188843/total_images/'+img)                 self.label.append(paddle.to_tensor(int(la), dtype='int64'))         else:             # 读test_images的数据             for img,la in zip(self.test_images, self.test_label):                 self.img.append('/home/aistudio/data/data188843/total_images/'+img)                 self.label.append(paddle.to_tensor(int(la), dtype='int64'))     def load_img(self, image_path):         # 实际使用时使用Pillow相关库进行图片读取即可,这里我们对数据先做个模拟         image = Image.open(image_path).convert('RGB')         # image = data_transforms(image)         return image     def __getitem__(self, index):         """         步骤三:实现__getitem__方法,定义指定index时如何获取数据,并返回单条数据(训练数据,对应的标签)         """         image = self.load_img(self.img[index])         LL, LH, HL, HH = fwdHaarDWT2D(image)         label = self.label[index]         # print(LL.shape)         # print(LH.shape)         # print(HL.shape)         # print(HH.shape)         LL = data_transforms(LL)         LH = data_transforms(LH)         HL = data_transforms(HL)         HH = data_transforms(HH)         print(type(LL))         print(LL.dtype)         return LL, LH, HL, HH, np.array(label, dtype='int64')     def __len__(self):         """         步骤四:实现__len__方法,返回数据集总数目         """         return len(self.img) image_file_txt = '/home/aistudio/data/data188843/total_images/train.txt' with open(image_file_txt) as fd:     lines = fd.readlines() train_img_list = list() train_label_list = list() for line in lines:     split_list = line.strip().split()     image_name, label_id = split_list     train_img_list.append(image_name)     train_label_list.append(label_id) # print(train_img_list) # print(train_label_list) # 测试定义的数据集 train_dataset = MyDataset(mode='train',train_label_list=train_label_list,  train_img_list=train_img_list, val_img_list=train_img_list, val_label_list=train_label_list) # test_dataset = MyDataset(mode='test') # 构建训练集数据加载器 train_loader = paddle.io.DataLoader(train_dataset, batch_size=2, shuffle=True) # 构建测试集数据加载器 valid_loader = paddle.io.DataLoader(train_dataset, batch_size=2, shuffle=True) print('=============train dataset=============') for LL, LH, HL, HH, label in train_dataset:     print('label: {}'.format(label))     break 模型训练model2 = paddle.Model(model_res) model2.prepare(optimizer=paddle.optimizer.Adam(parameters=model2.parameters()),               loss=nn.CrossEntropyLoss(),               metrics=paddle.metric.Accuracy()) model2.fit(train_loader,         valid_loader,         epochs=5,         verbose=1,         ) 
  • [技术干货] Python利用plotly绘制正二十面体详解【转】
    plotly 的 Python 软件包是一个开源的代码库,它基于 plot.js,而后者基于 d3.js。我们实际使用的则是一个对 plotly 进行封装的库,名叫 cufflinks,能让你更方便地使用 plotly 和 Pandas 数据表协同工作。一言以蔽之,plotly是一款擅长交互的Python绘图库,下面就初步使用一下这个库的三维绘图功能。此前曾经用matplotlib画了正二十面体和足球:Python绘制正二十面体;画足球,这次用plotly复现一下正二十面体的绘制过程,也体验一下这两个绘图包的差异。来绘制一个正二十面体。顶点正20面体的12个顶点刚好可以分为三组,每一组都是一个符合黄金分割比例的长方形,而且这三个长方形是互相正交的。所以,想绘制一个正二十面体是比较容易的 import plotly import plotly.express as px import numpy as np from itertools import product G = (np.sqrt(5)-1)/2 def getVertex():     pt2 =  [(a,b) for a,b in product([1,-1], [G, -G])]     pts =  [(a,b,0) for a,b in pt2]     pts += [(0,a,b) for a,b in pt2]     pts += [(b,0,a) for a,b in pt2]     return np.array(pts)  xs, ys, zs = getVertex().T  fig = px.scatter_3d(x=xs, y=ys, z=zs,      size=np.ones_like(xs)*0.5) fig.show() 棱接下来连接这12个顶点,由于点数较少,所以直接遍历也不至于运算量爆炸。另一方面,正二十面体边长相同,而这些相同的边连接的也必然是最近的点,所以接下来只需建立顶点之间的距离矩阵,并抽取出距离最短的线。 def getDisMat(pts):     N = len(pts)     dMat = np.ones([N,N])*np.inf     for i in range(N):         for j in range(i):             dMat[i,j] = np.linalg.norm([pts[i]-pts[j]])     return dMat  pts = getVertex() dMat = getDisMat(pts) # 由于存在舍入误差,所以得到的边的数值可能不唯一 ix, jx = np.where((dMat-np.min(dMat))<0.01) 接下来,绘制正二十面体的棱 edges = [] for k in range(len(ix)):     edges.append(pts[ix[k]].tolist() + [k])     edges.append(pts[jx[k]].tolist() + [k])  edges = np.array(edges)  fig = px.line_3d(edges, x=0, y=1, z=2, color=3) fig.show() 实现正二十面体接下来要对面上色。由于三棱成个面,所以只需得到所有三条棱的组合,只要这三条棱可以组成三角形,就能获取所有的三角面。当然,这一切的前提是,正二十面体只有30个棱,即使遍历多次,也无非27k的计算量,是完全没问题的。 def isFace(e1, e2, e3):     pts = np.vstack([e1, e2, e3])     pts = np.unique(pts, axis=0)     return len(pts)==3  edges = [pts[[i,j]] for i,j in zip(ix, jx)] from itertools import combinations faces = [es for es in combinations(edges, 3)      if isFace(*es)] 最后得到的faces有20个元素,每个元素由3条棱组成,每条棱有两个顶点,故而可以缩减为三个顶点。ptFace = [np.unique(np.vstack(f),axis=0) for f in faces] ptFace = np.vstack(ptFace)     接下来绘制一下,plotly绘制三角面的逻辑是,除了需要指定三角面的三个坐标之外,还需指定三角面的顶点序号import plotly.figure_factory as ff simplices = np.arange(len(ptFace)).reshape(-1,3) fig = ff.create_trisurf(x=ptFace[:,0],      y=ptFace[:,1], z=ptFace[:,2],     simplices=simplices) fig.show() 
  • 求个python的mltend库
    求个python的mltend库。有没有大佬分享一下,感谢。
  • [问题求助] 3.1.0适用版本
    3.1.0的设计器是不是不适用与win7系统?每次安装后都提示插件安装命令执行失败,或者是内置python异常什么的,控件那都是空的
  • [技术干货] python查找指定依赖包简介信息实现
    做python项目时,想安装某个依赖包的最新版本,但又不知道它的版本号具体到多少,因此需要搜索查看它的相关简介信息.原来的时候,可以直接通过pip搜索查看: pip search xxx.但如今,再用这种方式会报错:123pip search django ERROR: XMLRPC request failed [code: -32500]RuntimeError: PyPI no longer supports 'pip search' (or XML-RPC search). Please use https://pypi.org/search (via a browser) instead. See https://warehouse.pypa.io/api-reference/xml-rpc.html#deprecated-methods for more information.于是,得换另一种方法:pip_search,首先是安装pip_search:1pip install pip-search安装完毕后,直接使用可能会报错找不到pip_search.因为本文所讨论的是在linux环境下,而pip下载依赖模块的路径可能是在~/.local/bin,这个路径可能尚未加入到系统环境变量中,所以需要:123vi ~/.bashrc;export PATH=~/.local/bin:$PATH;source ~/.bashrc;使用示例:1pip_search django结果:12345678910111213141516171819202122232425262728293031🐍 https://pypi.org/search/?q=django 🐍                     ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓┃ Package                             ┃ Version ┃ Released   ┃ Description     ┃┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩│ 📂 Django                           │ 4.1.6   │ 01-02-2023 │ A high-level    ││                                     │         │            │ Python web      ││                                     │         │            │ framework that  ││                                     │         │            │ encourages      ││                                     │         │            │ rapid           ││                                     │         │            │ development and ││                                     │         │            │ clean,          ││                                     │         │            │ pragmatic       ││                                     │         │            │ design.         ││ 📂 django-503                       │ 0.1     │ 03-10-2011 │ An app to show  ││                                     │         │            │ 503 error page, ││                                     │         │            │ while your      ││                                     │         │            │ django site is  ││                                     │         │            │ on maintenance. ││ 📂 django-filebrowser-django13      │ 3.0     │ 14-03-2011 │ Media-Manageme… ││                                     │         │            │ with the Django ││                                     │         │            │ Admin-Interfac… ││                                     │         │            │ Package for     ││                                     │         │            │ using without   ││                                     │         │            │ django-grapelli ││                                     │         │            │ in Django 1.3   ││ 📂 django-tracking-analyzer-django2 │ 0.3     │ 02-01-2019 │ User actions    ││                                     │         │            │ tracking and    ││                                     │         │            │ analytics for   ││                                     │         │            │ Django sites. ......转载自https://www.jb51.net/article/274842.htm
  • [技术干货] 深入理解Python中__init__.py文件
    1. 简介1.1 模块(Module)和包(Package)的概念模块是程序,任何Python程序都可以作为模块导入。写在脚本.py文件中的函数,比如xx.py,可以在另一个模块或者脚本中通过import xx进行导入。如果要导入xx.py中的函数yy,就写成from xx import yy。可见模块可以简单的理解为一个.py文件。包就是模块所在的目录。和文件夹不同的是,包的根目录下存在__init__.py。一个文件夹根目录下存在__init__.py那就会认为该文件夹是Python包,否则那这个文件夹就是一个普通的文件夹。1.2 __init__.py文件简介__init__.py文件的作用是将文件夹变为一个Python的包,Python中每个包中,都有__init__.py文件。通常__init__.py文件为空,但是我们还可以为它增加其他的功能。我们在导入一个包时,实际上是导入了它的__init__.py文件。这样我们可以在__init__.py文件中批量导入我们所需要的模块,而不再需要一个一个的导入。2. __init__.py内容写法2.1 __init__.py文件内容以PySolid代码为例。PySolid包的目录结构如下:1234.├── grid.py├── point.py└── __init__.py__init__.py内容:123456789101112131415161718192021# top-level functionsfrom pysolid.grid import (    calc_solid_earth_tides_grid,    plot_solid_earth_tides_grid,)from pysolid.point import (    TIDES,    calc_solid_earth_tides_point,    plot_solid_earth_tides_point,    plot_power_spectral_density4tides,)__all__ = [    '__version__',    'calc_solid_earth_tides_grid',    'plot_solid_earth_tides_grid',    'TIDES',    'calc_solid_earth_tides_point',    'plot_solid_earth_tides_point',    'plot_power_spectral_density4tides',]2.2 __init__.py内容解释从grid.py中导入两个函数:12calc_solid_earth_tides_gridplot_solid_earth_tides_grid从point.py中导入四个函数:1234TIDES,calc_solid_earth_tides_pointplot_solid_earth_tides_pointplot_power_spectral_density4tides在__init__.py中通过定义__all__变量来控制外部调用者能够调用的范围,除了以下列表中的函数,其它函数都无法被使用,类似于私有函数或变量。123456789__all__ = [    '__version__',    'calc_solid_earth_tides_grid',    'plot_solid_earth_tides_grid',    'TIDES',    'calc_solid_earth_tides_point',    'plot_solid_earth_tides_point',    'plot_power_spectral_density4tides',]转载自https://www.jb51.net/article/274851.htm