从开发属于你自己的第一个 Python 库,做一名真正的程序员「双语版」
你好,我是悦创。之前我在 CSDN 编写了一篇开发 Python 库的教程,有人加我提问到的一些问题,我来更新一下这篇文章:https://blog.csdn.net/qq_33254766/article/details/119874997
新版文章首发:https://bornforthis.cn/posts/18.html
你好,我是悦创。
Hello, I'm Yue Chuang.
我最近想要去开始开发 Python 第三方库,但是发现国内这样的教程太少了,所以就我来写吧!
I recently wanted to start developing Python third-party libraries, but found that there are too few such tutorials in the country, so I will write them instead!
还有就是曾经想创建一个 Python 库,无论是为您的工作团队还是在线的一些开源项目?在此博客中,您将学习如何操作!
Ever wanted to create a Python library, albeit for your team at work or for some open source project online? In this blog you will learn how to!
当您使用相同的开发工具 Pycharm ,你会最容易跟上我的教程,当然您也可以使用不同的工具。
The tutorial is easiest to follow when you are using the same tools, however it is also possible for you to use different ones.
本文章使用的是工具有:
The tools used in this tutorial are:
- MacOS「其实,不管你使用何种电脑都可以」MacOS command prompt
- Pycharm「社区版本足已」
第 0 步:MacOS 命令行命令「Step 0: MacOS command line command」
打开命令提示符并创建一个文件夹,您将在其中创建 Python 库。
Open your command prompt and create a folder in which you will create your Python library.
请记住:
Remember:
pwd
您可以看到您当前的工作目录。 「Withpwd
you can see your present working directory.」ls
您可以列出当前目录中的文件夹和文件。 「Withls
you can list the folders and files in your directory.」cd <path>
您可以更改当前所在的目录。 「Withcd <path>
you can change the current present directory you are in.」mkdir <folder>
您可以在当前工作目录中创建一个新文件夹。 「Withmkdir <folder>
you can create a new folder in your working directory.」
第 1 步:创建一个要放置库的目录「Step 1: Create a directory in which you want to put your library」
我创建一个文件夹名为:Turingaiyc,这个名称其实也是我后面发布库的名称,注意不要太普遍因为会重复,重复就会导致发布库失败。
I created a folder called Turingaiyc, which is actually the name of the library I will publish later. Be careful not to make it too common because it will be repetitive, which will cause the library to fail.
「PS:你如果 Win 系统的话,可以使用下面的命令,如果是 MacOS 的话我其实更喜欢命令行创建。」
I created a folder called Turingaiyc, which is actually the name of the library I will publish later. Be careful not to make it too common because it will be repetitive, which will cause the library to fail.
就我而言,我将使用的文件夹是 Turingaiyc
。将当前工作目录更改为您的文件夹。
In my case, the folder I will be working with is
Turingaiyc
. Change the present working directory to be your folder.
第 2 步:为您的文件夹创建一个虚拟环境「Step 2: Create a virtual environment for your folder」
在启动您的项目时,创建一个虚拟环境来封装您的项目总是一个好主意。虚拟环境由某个 Python 版本和一些库组成。
When starting your project, it is always a good idea to create a virtual environment to encapsulate your project. A virtual environment consists of a certain Python version and some libraries.
Reference: Such a full Python virtual environment? What a pity!
虚拟环境可防止以后遇到依赖性问题。 例如,在较旧的项目中,您可能使用的是较旧版本的 numpy 库。一些曾经运行良好的旧代码可能会在你更新 numpy 版本后不能正常运行了。 创建虚拟环境可以防止这种情况,当你与其他人协作时,虚拟环境也能确保你的程序在其他人的电脑上正常运行。 反之亦然。
Virtual environments prevent the issue of running into dependency issues later on. For example, in older projects you might have worked with older versions of the
numpy
library. Some old code, that once worked beautifully, might stop working once you update its version. Perhaps parts ofnumpy
are no longer compatible with other parts of your program. Creating virtual environments prevents this. They are also useful in cases when you are collaborating with someone else, and you want to make sure that your application is working on their computer, and vice versa.
接下来,你要确保你当前的工作目录是你刚刚创建的目录,( cd <path/to/folder>
) 中创建 Python 库的文件夹。)
(Make sure you changed the present working directory to the folder you are going to create your Python library in (
cd <path/to/folder>
).)
继续并通过键入以下内容创建虚拟环境:
Go ahead and create a virtual environment by typing:
python3 -m venv venv
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yy0tslPL-1656388442132)(./18.assets/image-20220617224826141.png)]
创建后,你现在必须使用以下命令激活环境:
Once it is created, you must now activate the environment by using:
source venv/bin/activate
激活虚拟环境会修改 PATH 和 shell 的变量,以指向您创建的特定虚拟环境 Python 的设置。PATH 是 MacOS/Linux 和其他类 Unix 操作系统中的环境变量,它告诉 shell 在响应用户发出的命令时,去搜索哪些目录的 Python 执行环境(即准备运行的程序)。命令提示符将更改为通过添加 ( yourenvname) 来指示您当前所在的虚拟环境。
Activating a virtual environment modifies the PATH and shell variables to point to the specific isolated Python set-up you created. PATH is an environmental variable in Linux and other Unix-like operating systems that tells the shell which directories to search for executable files (i.e., ready-to-run programs) in response to commands issued by a user. The command prompt will change to indicate which virtual environment you are currently in by prepending (
yourenvname
).
你要确保你的环境已经安装了 pip、wheel、setuptools、twine。我们稍后将需要它们来构建我们的 Python 库。
In your environment, make sure you have pip installed
wheel
,setuptools
andtwine
. We will need them for later to build our Python library.
pip install wheel
pip install setuptools
pip install twine
或者也可以一条命了实现:
Or it can be done with one life:
sudo pip install wheel setuptools twine
我用的是 MacOS 所以,Windows 的话,去掉 sudo。
I'm using MacOS so for Windows, get rid of Sudo.
第 3 步:创建文件夹结构「Step 3: Create a folder structure」
这一步,也就是创建我们开发库所需要的文件。 在 Pycharm 中,打开您的文件夹 mypythonlibrary(或你自己创建的文件夹名称)。它应该是这样的:
In Pycharm, open your folder mypythonlibrary (or any name you have given your folder). It should look something like this:
你现在可以开始向项目添加文件夹和文件。您可以通过命令提示符或在 Pycharm 本身中执行此操作。
You now can start adding folders and files to your project. You can do this either through the command prompt or in Pycharm itself.
- 创建一个名为
setup.py
的空文件,这是创建 Python 库时最重要的文件之一!「Create an empty file calledsetup.py
. This is one of the most important files when creating a Python library!」 - 创建一个名为
README.md
的空文件,你可以在此处编写 Markdown 以向其他用户描述我们的库内容。「Create an empty file calledREADME.md
. This is the place where you can write markdown to describe the contents of your library for other users.」 - 创建一个名为
TuringRobots
,或者任何您希望在 pip 安装时调用 Python 库的文件夹。(如果你想稍后发布它,该名称在 pip 上应该是唯一的。)「Create a folder calledTuringRobots
, or whatever you want your Python library to be called when you pip install it. (The name should be unique on pip if you want to publish it later.)」 - https://pypi.org/search/?q=TuringRobots 后面的 TuringRobots 修改成你自己的库名字,之后打开浏览器访问,看是否有这个库。
- 在
TuringRobots
文件夹里面,创建名为__init__.py
的空文件。基本上,任何包含文件的__init__.py
文件夹,在我们构建它时,都将包含在库中。大多数情况下,您可以将__init__.py
文件留空,也就是不用写代码。在导入时,其中的__init__.py
里面的代码将被执行,因此它应该只包含能够运行项目所需的最少量代码。现在,我们将它保持原样。「Create an empty file insidemypythonlib
that is called__init__.py
. Basically, any folder that has an__init__.py
file in it, will be included in the library when we build it. Most of the time, you can leave the__init__.py
files empty. Upon import, the code within__init__.py
gets executed, so it should contain only the minimal amount of code that is needed to be able to run your project. For now, we will leave them as is.」 - 此外,在
TuringRobots
文件夹中,创建一个名为TuringRobots.py
「Also, in the same folder, create a file calledTuringRobots.py
.」 - 最后,在您的根文件夹中创建一个文件夹测试。在里面,创建一个空
__init__.py
文件和一个空的test_myfunctions.py
「And, finally, create a folder tests in your root folder. Inside, create an empty__init__.py
file and an emptytest_myfunctions.py
.」
你所创建的文件夹和代码文件,现在应如下所示:
Your set-up should now look something like this:
第 4 步:为您的库创建内容「Step 4: Create content for your library」
要将函数放入库中,您可以将它们放入 TuringRobots.py
文件中。例如,复制文件中的 TuringRobots 函数:
To put functions inside your library, you can place them in the
TuringRobots.py
file. For example, copy the TuringRobots function in your file:
# -*- coding: utf-8 -*-
# @Time : 2022/6/18 11:34
# @Author : AI悦创
# @FileName: TuringRobots.py
# @Software: PyCharm
# @Blog :https://bornforthis.cn/
import json
import urllib.request
import os
from dotenv import load_dotenv
def TuringRobots(text, over_print=True):
load_dotenv()
api_url = "http://openapi.tuling123.com/openapi/api/v2"
req = {
"reqType": 0,
"perception":
{
"inputText":
{
"text": text
},
"selfInfo":
{
"location":
{
"city": "厦门",
"province": "厦门",
"street": "海沧区"
}
}
},
"userInfo":
{
"apiKey": os.getenv("API_KEY"),
"userId": "OnlyUseAlphabet"
}
}
# print(req)
# 将字典格式的req编码为utf8
req = json.dumps(req).encode('utf8')
# print(req)
http_post = urllib.request.Request(api_url, data=req, headers={'content-type': 'application/json'})
response = urllib.request.urlopen(http_post)
response_str = response.read().decode('utf8')
# print(response_str)
response_dic = json.loads(response_str)
# print(response_dic)
intent_code = response_dic['intent']['code']
results_text = response_dic['results'][0]['values']['text']
if over_print:
print('Turing的回答:')
print('code:' + str(intent_code))
print('text:' + results_text)
else:
return (str(intent_code), results_text)
if __name__ == '__main__':
text = input("请输入你的对话:")
code, content = TuringRobots(text, over_print=False)
print(code, content)
上面实现了一个简单的机器人对话,对于 Python 测试,可以使用 pytest 和 pytest-runner 库。在虚拟环境中安装库:
A simple robot dialogue is implemented above, For testing with Python you can use the libraries
pytest
andpytest-runner
. Install the library in your virtual environment:
pip install pytest
pip install pytest-runner
pip install python-dotenv
让我们为项目创建一个小测试,测试如下:
Let's create a small test for the project that looks like this:
TuringRobots_Tests.py
from TuringRobots import TuringRobots
def test_TuringRobots():
assert TuringRobots.TuringRobots("我是天才,那你呢?", over_print=True)
最后,让我们创建一个 setup.py
文件,它将帮助我们构建库。setup.py
的内容如下所示:
Finally, let’s create a
setup.py
file, that will help us to build the library. A limited version ofsetup.py
will look something like this:
from setuptools import find_packages, setup
setup(
name='mypythonlib',
packages=find_packages(),
version='0.1.0',
description='My first Python library',
author='Me',
license='MIT',
)
我的设置:【你们看简洁的配置即可】
# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time : 2022/6/18 11:51
# @Author : AI悦创
# @FileName: setup.py
# @Software: PyCharm
# @Blog :https://bornforthis.cn/
# Note: To use the 'upload' functionality of this file, you must:
# $ pipenv install twine --dev
import io
import os
import sys
from shutil import rmtree
from setuptools import find_packages, setup, Command
# Package meta-data.
NAME = 'TuringRobots'
DESCRIPTION = 'Simple dialogue test Turing robot.'
URL = 'https://github.com/AndersonHJB/TuringRobots'
EMAIL = 'bornforthis@bornforthis.cn'
AUTHOR = 'Bornforthis'
REQUIRES_PYTHON = '>=3.6.0'
VERSION = '1.2.5'
# What packages are required for this module to be executed?
REQUIRED = [
# 'dotenv==0.0.5',
]
# What packages are optional?
EXTRAS = {
# 'fancy feature': ['django'],
}
# The rest you shouldn't have to touch too much :)
# ------------------------------------------------
# Except, perhaps the License and Trove Classifiers!
# If you do change the License, remember to change the Trove Classifier for that!
here = os.path.abspath(os.path.dirname(__file__))
# Import the README and use it as the long-description.
# Note: this will only work if 'README.md' is present in your MANIFEST.in file!
try:
with io.open(os.path.join(here, 'README.md'), encoding='utf-8') as f:
long_description = '\n' + f.read()
except FileNotFoundError:
long_description = DESCRIPTION
# Load the package's __version__.py module as a dictionary.
about = {}
if not VERSION:
project_slug = NAME.lower().replace("-", "_").replace(" ", "_")
with open(os.path.join(here, project_slug, '__version__.py')) as f:
exec(f.read(), about)
else:
about['__version__'] = VERSION
class UploadCommand(Command):
"""Support setup.py upload."""
description = 'Build and publish the package.'
user_options = []
@staticmethod
def status(s):
"""Prints things in bold."""
print('\033[1m{0}\033[0m'.format(s))
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
try:
self.status('Removing previous builds…')
rmtree(os.path.join(here, 'dist'))
except OSError:
pass
self.status('Building Source and Wheel (universal) distribution…')
os.system('python3 -m build')
# os.system('{0} setup.py sdist bdist_wheel --universal'.format(sys.executable))
# os.system('{0} setup.py sdist build --universal'.format(sys.executable))
# os.system('{0} setup.py sdist build --universal'.format(sys.executable))
self.status('Uploading the package to PyPI via Twine…')
os.system('twine upload dist/*')
self.status('Pushing git tags…')
os.system('git tag v{0}'.format(about['__version__']))
os.system('git push --tags')
sys.exit()
# Where the magic happens:
setup(
name=NAME,
version=about['__version__'],
description=DESCRIPTION,
long_description=long_description,
long_description_content_type='text/markdown',
author=AUTHOR,
author_email=EMAIL,
python_requires=REQUIRES_PYTHON,
url=URL,
# packages=find_packages(exclude=["tests", "*.tests", "*.tests.*", "tests.*"]),
# packages=find_packages(exclude=["TuringRobots", ]),
packages=find_packages(include=["TuringRobots",]),
# If your package is a single module, use this instead of 'packages':
# py_modules=['mypackage'],
# entry_points={
# 'console_scripts': ['mycli=mymodule:cli'],
# },
install_requires=REQUIRED,
# setup_requires=['pytest-runner'],
# tests_require=['pytest'],
# tests_require=['pytest', 'dotenv'],
test_suite='tests',
extras_require=EXTRAS,
include_package_data=True,
license='MIT',
classifiers=[
# Trove classifiers
# Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
'License :: OSI Approved :: MIT License',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy'
],
# $ setup.py publish support.
cmdclass={
'upload': UploadCommand,
},
)
第 5 步:设置您想要创建的包「Set the packages you would like to create」
setup 中的 name 变量保存您希望包轮文件具有的任何名称。为了方便起见,我们将其命名为与文件夹相同的名称。
The name variable in setup holds whatever name you want your package wheel file to have. To make it easy, we will gave it the same name as the folder.
虽然原则上 find_packages()
可以不带任何参数使用,但这可能会导致包含不需要的包。 所以,我们可以这么来写:
例如,如果您在 tests/
目录中包含 __init__.py
, 就会发生这种情况。另外,您也可以使用 exclude 参数显式地阻止在包中包含测试,但是这样做稍微不那么健壮。让我们把它改为如下:
from setuptools import find_packages, setup
setup(
name='mypythonlib',
packages=find_packages(include=['mypythonlib']),
version='0.1.0',
description='My first Python library',
author='Me',
license'MIT',
)
第 6 步:设置库所需的要求「Set the requirements your library needs」
注意,当你的项目被其他人作为依赖项安装时,pip 不会使用requirements.yml
/ requirements.txt
。 通常,为此,您必须在 setup.py
文件的 install_requires
和 tests_require
参数中指定依赖项。
Note that pip does not use
requirements.yml
/requirements.txt
when your project is installed as a dependency by others. Generally, for that, you will have to specify dependencies in theinstall_requires
andtests_require
arguments in yoursetup.py
file.
Install_requires
应该仅限于绝对需要的软件包列表。这是因为您不想让用户安装不必要的软件包。 另请注意,你不需要列出属于标准 Python 库的包。
Install_requires
should be limited to the list of packages that are absolutely needed. This is because you do not want to make users install unnecessary packages. Also note that you do not need to list packages that are part of the standard Python library.
如果你用的是 Python 自带的库,是可以不用写的,并且保证这个库是一直到现在的 Python 本版的可以使用的。 也许你还记得我们 pytest
、numpy
之前安装过这个库。当然,你不想在其中添加 pytest
依赖项。这个包的用户不需要它。为了仅在运行测试时自动安装它,您可以将以下内容添加到您的 setup.py
:
from setuptools import find_packages, setup
setup(
name='mypythonlib',
packages=find_packages(include=['mypythonlib']),
version='0.1.0',
description='My first Python library',
author='Me',
license='MIT',
install_requires=[],
setup_requires=['pytest-runner'],
tests_require=['pytest==4.4.1'],
test_suite='tests',
)
运行:将执行存储在 “tests” 文件夹中的所有测试。
python setup.py pytest
Running:
> python setup.py pytest
will execute all tests stored in the ‘tests’ folder.
下面是简单的代码测试输出:
(venv) aiyc@aiyc:~/Linux_Code/mypythonlibrary$ python setup.py pytest
running pytest
running egg_info
creating mypythonlib.egg-info
writing mypythonlib.egg-info/PKG-INFO
writing dependency_links to mypythonlib.egg-info/dependency_links.txt
writing requirements to mypythonlib.egg-info/requires.txt
writing top-level names to mypythonlib.egg-info/top_level.txt
writing manifest file 'mypythonlib.egg-info/SOURCES.txt'
reading manifest file 'mypythonlib.egg-info/SOURCES.txt'
writing manifest file 'mypythonlib.egg-info/SOURCES.txt'
running build_ext
================================================================ test session starts =================================================================
platform linux -- Python 3.8.10, pytest-6.2.4, py-1.10.0, pluggy-0.13.1
rootdir: /home/aiyc/Linux_Code/mypythonlibrary
collected 1 item tests/test_myfunctions.py .
第 7 步:构建你的库「Step 5: Build your library」
现在所有内容都已准备就绪,我们要构建我们的库。确保您当前的工作目录是 /path/to/mypythonlibrary
(因此是项目的根文件夹)。在您的命令提示符中,运行:
Now that all the content is there, we want to build our library. Make sure your present working directory is
/path/to/mypythonlibrary
(so the root folder of your project). In your command prompt, run:
python setup.py bdist_wheel
您的轮文件存储在现在创建的 “dist” 文件夹中。您可以使用以下方法安装您的库:
Your wheel file is stored in the “dist” folder that is now created. You can install your library by using:
pip install /path/to/wheelfile.whl
请注意,您还可以将您的库发布到您工作场所内联网上的内部文件系统,或发布到官方 PyPI 存储库并从那里安装它。 安装 Python 库后,您可以使用以下命令导入它:
Note that you could also publish your library to an internal file system on intranet at your workplace, or to the official PyPI repository and install it from there.Once you have installed your Python library, you can import it using:
import mypythonlib
from mypythonlib import myfunctions
我自己使用如下官方构建:
python3 -m pip install --upgrade build
python3 -m build
# 测试代码
python setup.py pytest
# 提交代码
python setup.py upload
参考文章:
- 如何创建 Python 库
- https://packaging.python.org/en/latest/tutorials/packaging-projects/
- https://packaging.python.org/en/latest/specifications/pypirc/
- https://medium.com/analytics-vidhya/how-to-create-a-python-library-7d5aea80cc3f
- https://medium.com/@alexbebereche/how-to-hide-you-api-key-with-python-5cc63d2a6c45
欢迎关注我公众号:AI悦创,有更多更好玩的等你发现!
::: details 公众号:AI悦创【二维码】
::: info AI悦创·编程一对一
AI悦创·推出辅导班啦,包括「Python 语言辅导班、C++ 辅导班、java 辅导班、算法/数据结构辅导班、少儿编程、pygame 游戏开发」,全部都是一对一教学:一对一辅导 + 一对一答疑 + 布置作业 + 项目实践等。当然,还有线下线上摄影课程、Photoshop、Premiere 一对一教学、QQ、微信在线,随时响应!微信:Jiabcdefh
C++ 信息奥赛题解,长期更新!长期招收一对一中小学信息奥赛集训,莆田、厦门地区有机会线下上门,其他地区线上。微信:Jiabcdefh
方法一:QQ
方法二:微信:Jiabcdefh
从开发属于你自己的第一个 Python 库,做一名真正的程序员「双语版」的更多相关文章
- 敏捷软件开发:原则、模式与实践——第13章 写给C#程序员的UML概述
第13章 写给C#程序员的UML概述 UML包含3类主要的图示.静态图(static diagram)描述了类.对象.数据结构以及它们之间的关系,藉此表现出了软件元素间那些不变的逻辑结构.动态图(dy ...
- Python开发还在用virtualenv?不如了解下pipenv...#华为云·寻找黑马程序员#
又见 Kenneth Reitz 之前公众号写了一篇文章爬虫新宠requests_html 带你甄别2019虚假大学,其中主要是为了介绍模块**requests_html,这个模块的作者还开发了req ...
- 「2.0」一个人开发一个App,小程序从0到1,文件剖析
不知你是不是见到“文件剖析”这4个大字,才点进来看一看的?如果真是的话,那我可以坦诚.真心.负责任地告诉你:你上当了,你上了贼船啦,如果你现在想跳的话,还来得及,反正茫茫大海中,鲨鱼正缺搞程序的人.说 ...
- PHP程序员如何突破成长瓶颈(php开发三到四年)
看了这篇博文,我正好处于这个阶段,也有心要突破自己,呵呵! 作为Web开发中应用最广泛的语言之一,PHP有着大量的粉丝,那么你是一名优秀的程序员吗?在进行自我修炼的同时,你是否想过面对各种各样的问题, ...
- 程序员带你十天快速入门Python,玩转电脑软件开发(二)
关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...
- 对ios、android开发程序员的14条忠告
————————本文摘自千锋教育(http://www.mobiletrain.org/)对ios\android开发程序员的14条忠告————————— 1.不要害怕在工作中学习. 只要有电脑,就可 ...
- 4年前端、2年CTO:一个非科班程序员的真实奋斗史
1.引言 我,Scott,一家创业公司的 CTO. 从业6年却很少写文章,近一年来接触了几十个刚毕业的前端新人,也面试了100多个前端工程师和Nodejs工程师,对于前端发展的这个职业算是有些感触 ...
- 一个六年Java程序员的从业总结:比起掉发,我更怕掉队
我一直担惊受怕,过去,可能是因为我年轻,但现在,我已经不是那么年轻了,我仍然发现有很多事情让我害怕. 当年纪越来越大后,我开始变得不能加班.我开始用更多的时间和家人在一起,而不是坐在计算机前(尽管这样 ...
- 一个java程序员的年终总结
年底了,该给自己写点总结了! 从毕业到现在已经快4年啦,一直在Java的WEB开发行业混迹.我不是牛人,但是自我感觉还算是个合格的程序员,有必要写下自己将近4年来的经历,给自我以提示,给刚入行的朋友提 ...
- 文章推荐一个Java程序员跟大家谈谈从业心得
一个Java程序员跟大家谈谈从业心得 2017-10-21 java那些事 java那些事 java那些事 微信号 csh624366188 功能介绍 分享java开发中常用的技术,分享软件开发中各种 ...
随机推荐
- Servlet(处理乱码,重定向与转发的区别)
//处理请求乱码 req.setCharacterEncoding("utf-8"); //处理响应乱码 resp.setContentType("text/html;c ...
- Linux 下搭建 Hive 环境
Linux 下搭建 Hive 环境 作者:Grey 原文地址: 博客园:Linux 下搭建 Hive 环境 CSDN:Linux 下搭建 Hive 环境 前置工作 首先,需要先完成 Linux 下搭建 ...
- map集合类型/实体类类型的参数
map集合类型的参数 若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合, 将这些数据放在map中 只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要 ...
- SpringBoot框架SpEL表达式注入漏洞复现与原理分析
前言 这是2016年的一个洞,利用条件是至少知道一个触发 springboot 默认错误页面的接口及参数名. 影响版本:1.1.0-1.1.12 1.2.0-1.2.7 1.3.0 修复方案:升级版本 ...
- go-zero docker-compose 搭建课件服务(二):编写courseware rpc服务
0.转载 go-zero docker-compose 搭建课件服务(二):编写courseware rpc服务 0.1源码地址 https://github.com/liuyuede123/go-z ...
- linux 2021
常用安装 sudo apt install openssh-server # 安装ssh service ssh # 查看ssh服务的 基础 Debian 是Ubuntu的母板,有强大的包管理功能,使 ...
- centos使用lftp备份文件
一直以来项目的文件没有备份,最近需要增加备份,本来以为备份是IT的工作,结果IT说工作忙,拖了半个月给分配完ftp服务器后说不给备份,需要我们开发自己备份...我特么*** 对于ftp备份,咱是没有经 ...
- Optional对象
Optional对象 Optional 类是一个可以为null的容器对象,用于简化Java中对空值的判断处理,以防止出现各种空指针异常. 静态方法-of 必须确定对象不为null 在使用of封装成op ...
- SPPS完整版下载安装教程【博主亲测】
SPSS全称Statistical Product and Service Solutions,是一款优秀的数据分析软件,旨在为用户提供专业的统计产品与服务解决方案.SPSS面向行业应用人员所设,被广 ...
- Kubernetes_从云原生到kubernetes
一.前言 二.kubernetes和云原生 Cloud Native 直接翻译为云原生,云原生官网:https://www.cncf.io/ CNCF,表示 Cloud Native Computin ...