python botos s3 aws
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html
AWS是亚马逊的云服务,其提供了非常丰富的套件,以及支持多种语言的SDK/API。本文针对其S3云储存服务的Python SDK(boto3)的使用进行介绍。
关键词:AWS,S3,Python,boto3,endpoint,client
背景
AWS是一整套亚马逊云服务套件(云存储及其上的基础设施和服务),包括云存储(主要是对象存储)、微服务、数据库等,其中S3对象存储受到众多国内开发者的欢迎。AWS提供了包括console、client、sdk等多种方式进行连接使用,并支持包括python在内的许多语言。为了便捷地在Python程序内使用S3对象存储,我们考虑两种途径:
- 在子进程中召唤aws client命令行程序;
- 在python中调用boto3模块的api调用服务
其中boto3途径由于和python语言(和其他语言)有较好的适配,因此更适合开发者使用。此外,处于安全考虑,开发者可能只能获得AWS的有限访问权限,比如endpoint,这使得aws官方教程中的一些范例不可用。比如,访问对象存储至少存在三种方式:Resource、Session、Client,而借助endpoint我们只能访问client,这限制了开发者权限、无法使用高级功能的同时,也提高了数据操作的安全性。
本文将针对如何调用boto3和endpoint来实现aws S3服务的功能进行介绍。
相关信息
在正式介绍之前,有必要对aws及boto3的相关组件和功能进行介绍。
从AWS到S3
从AWS到其中的S3服务的关系链可以简单地描述为:AWS -> VPC -> S3 -> Endppoint -> EC2
意思是AWS到私有云(VPC)到S3存储到EC2服务实例,Endpoint则是S3到EC2的桥梁。如下图所示:
“Amazon Virtual Private Cloud (Amazon VPC),简单理解,就是在云上建个大楼,大楼里面的网络、门禁,安检等都一应俱全,我们根据需要在大楼里选择房间(创建ec2)办公,这个房间自己也有相应的门禁系统”
参考:https://www.bioaws.com/blogs/2020-02-02-vpc-endpoint-s3/
AWS的命令行client
aws提供了一个便捷的命令行程序以供使用,其需要先去官网下载一个zip安装包,然后解压安装即可:
安装aws cli:How to Install AWS CLI on Ubuntu 20.04
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
配置awscli
aws configure
# 输入access key和security key:后两项可以忽略(假如只需要使用S3的话)
连接S3存储桶
# view folder
aws [option] --endpoint-url [endpoint_url] s3 [action] s3://[bucket]
# download single file
aws [option] --endpoint-url [endpoint_url] s3 cp s3://[bucket]/[file_path] [local_path]
# download folder
aws [option] --endpoint-url [endpoint_url] s3 sync s3://[bucket]/[folder_path] [local_path]
参考:通过 AWS CLI 使用高级别 (s3) 命令
boto3: python sdk
SimpleQueueService(SQS)
Amazon Simple Queue Service (Amazon SQS) 是一种完全托管的消息队列服务,可以轻松解耦和扩展微服务、分布式系统和无服务器应用程序。 Amazon SQS 在分布式应用程序组件之间移动数据并帮助您解耦这些组件。
import boto3'''send messages'''
# Get the service resource
sqs = boto3.resource('sqs')
# Get the queue
queue = sqs.get_queue_by_name(QueueName='test')
# Create a new message
response = queue.send_message(MessageBody='world')
# The response is NOT a resource, but gives you a message ID and MD5
print(response.get('MessageId'))
print(response.get('MD5OfMessageBody'))'''process messages'''
# Process messages by printing out body and optional author name
for message in queue.receive_messages(MessageAttributeNames=['Author']):# Get the custom author message attribute if it was setauthor_text = ''if message.message_attributes is not None:author_name = message.message_attributes.get('Author').get('StringValue')if author_name:author_text = ' ({0})'.format(author_name)# Print out the body and author (if set)print('Hello, {0}!{1}'.format(message.body, author_text))# Let the queue know that the message is processedmessage.delete()
Resource
资源表示 Amazon Web Services (AWS) 的面向对象的接口。 它们提供了比服务客户端进行的原始低级调用更高级别的抽象。
每个资源实例都有许多属性和方法。 这些在概念上可以分为标识符、属性、操作、引用、子资源和集合。资源本身也可以在概念上分为服务资源(如 sqs、s3、ec2 等)和单个资源(如 sqs.Queue 或 s3.Bucket)。 服务资源没有标识符或属性。 否则,两者共享相同的组件。
# Get resources from the default session
sqs = boto3.resource('sqs')
s3 = boto3.resource('s3')'''example'''
# S3 Object (bucket_name and key are identifiers)
obj = s3.Object(bucket_name='boto3', key='test.py')
print(obj.bucket_name)print(obj.key)# S3 Object attributes
obj.last_modifie
dobj.e_tag# S3 Object actions
obj = s3.Object(bucket_name='boto3', key='test.py')
response = obj.get()
data = response['Body'].read()# S3 sub-resources
obj = bucket.Object(key='new_file.txt')
print(obj.bucket_name)
print(obj.key)# S3: Wait for a bucket to exist.
bucket.wait_until_exists()
资源实例不是线程安全的,不应跨线程或进程共享。 这些特殊类包含无法共享的附加元数据。 建议在多线程或多处理中为每个线程或进程创建一个新资源。
Collections
集合为一组资源提供了一个可迭代的接口。
Session
会话管理有关特定配置的状态。 会话通常存储以下内容:
- 证书
- AWS 区域
- 与您的个人资料相关的其他配置
'''Using the default session'''
sqs = boto3.client('sqs')
s3 = boto3.resource('s3')'''Create your own session'''
my_session = boto3.session.Session()
# Now we can create low-level clients or resource clients from our custom session
sqs = my_session.client('sqs')
s3 = my_session.resource('s3')
与 Resource 对象类似,Session 对象不是线程安全的,不应在线程和进程之间共享。 建议在多线程或多处理中为每个线程或进程创建一个新的 Session 对象。
Client
客户端为 AWS 提供了一个低级接口,其方法与服务 API 的映射接近 1:1。 所有服务操作均由客户端支持。
import boto3
sqs = boto3.client('sqs')# It is also possible to access the low-level client from an existing resource:
# Create the resource
sqs_resource = boto3.resource('sqs')
# Get the client from the resource
sqs = sqs_resource.meta.client# send messages
response = sqs.send_message(QueueUrl='...', MessageBody='...')
# handling messages
response = sqs.list_queues()
for url in response.get('QueueUrls', []):print(url)
# waiters
sqs.waiter_names
多处理:虽然客户端是线程安全的,但由于它们的网络实现,它们不能跨进程共享。 这样做可能会导致调用服务时响应顺序不正确。
共享元数据:客户端通过一些属性(即元、异常和服务员名称)向最终用户公开元数据。 这些是可以安全阅读的,但任何突变都不应该被认为是线程安全的。
自定义 Botocore 事件:Botocore(构建 Boto3 库)允许高级用户提供他们自己的自定义事件挂钩,这些挂钩可以与 boto3 的客户端交互。 大多数用户不需要使用这些接口,但是那些不需要仔细审查的用户不应再考虑他们的客户端线程安全。
参考:Botocore Events - botocore 1.27.25 documentation
import boto3.session
from concurrent.futures import ThreadPoolExecutordef do_s3_task(client, task_definition):# Put your thread-safe code heredef my_workflow():# Create a session and use it to make our clientsession = boto3.session.Session()s3_client = session.client('s3')# Define some work to be done, this can be anythingmy_tasks = [ ... ]# Dispatch work tasks with our s3_clientwith ThreadPoolExecutor(max_workers=8) as executor:futures = [executor.submit(do_s3_task, s3_client, task) for task in my_tasks]
Endpoint (AWS PrivateLink for S3)
在将 S3 客户端配置为使用接口 VPC 终端节点时,请务必注意,只有终端节点中指定的资源类型才能使用该客户端进行寻址( only the resource type specified in the endpoint can be addressed)。 访问存储桶和访问点需要实例化两个客户端,每个资源类型一个。
import boto3
s3_client = boto3.client(service_name='s3',endpoint_url='https://bucket.vpce-abc123-abcdefgh.s3.us-east-1.vpce.amazonaws.com')
Paginators
一些 AWS 操作返回的结果不完整,需要后续请求才能获得整个结果集。 发送后续请求以在前一个请求中断的地方继续的过程称为分页。
Error handling
Boto3 提供了许多功能来帮助导航您在与 AWS 服务交互时可能遇到的错误和异常。
1. 确定要捕获的异常
- Botocore 异常
- AWS 服务异常:AWS 服务异常被底层的 botocore 异常 ClientError 捕获。有关您正在使用的服务的错误响应的完整列表,请参阅各个服务的 AWS 文档。
2. 使用低级客户端时捕获异常
3. 解析错误响应并从 AWS 服务中捕获异常
4. 从错误响应中辨别有用信息
try:client.some_api_call(SomeParam='some_param')except botocore.exceptions.ClientError as error:# Put your error handling logic hereraise errorexcept botocore.exceptions.ParamValidationError as error:raise ValueError('The parameters you provided are incorrect: {}'.format(error))'''Error message structure
{'Error': {'Code': 'SomeServiceException','Message': 'Details/context around the exception or error'},'ResponseMetadata': {'RequestId': '1234567890ABCDEF','HostId': 'host ID data will appear here as a hash','HTTPStatusCode': 400,'HTTPHeaders': {'header metadata key/values will appear here'},'RetryAttempts': 0}
}except botocore.exceptions.ClientError as err:if err.response['Error']['Code'] == 'InternalError': # Generic errorprint('Error Message: {}'.format(err.response['Error']['Message']))
'''
使用boto3操作S3
准备工作
考虑以下问题:
1. 你有什么访问权限? 在使用low-level client处理存储桶时,必须使用具有访问 ID/密钥的端点(Endpoint with access id / key)。 如果您想在 AWS 中尝试其他高级服务,请检查您的授权。 所拥有的 AWS 权限决定使用什么链接方式
2. 您处理的文件的大小。 请参考file-size limitation和File transfer configuration。 操作文件的大小
- 本地-> AWS:多部分
- AWS -> 本地:分页器
3.错误处理策略。 异常处理
- 单文件进程中断:同名再次上传并重写
- 文件夹进程中断:检查数据库,上传和重写
- 重复处理:检查数据库,上传和重写
- 线程安全:创建单个客户端来处理所有文件
4. 快速api参考。 API查询
- S3 — Boto3 Docs 1.24.24 文档
- 代码样例:Amazon S3 examples
- 会话参考 ‒ Boto3 Docs 1.24.24 文档
查询/上传/下载/删除 操作step-by-step
本节介绍了如何利用endpoint连接存储并操作。
- Configure aws
aws configure
# -> input aws_access_key_id & aws_secret_access_key
然后你会在 ~/.aws/credentials 找到你的配置文件。也可以忽略这一步,在python程序中设置。
2. Create an s3 client & explore buckects(查询)
s3_client = boto3.client(service_name='s3', endpoint_url=aws_s3_endpoint_url)
response = s3_client.list_buckets()
buckets = [bucket['Name'] for bucket in response['Buckets']]
print(buckets)
3. Upload files(上传,覆盖写)
s3默认采用覆盖写模式,如果希望避免这一问题,可以认为设置version属性进行控制。
response = s3_client.upload_file(local_file_path, bucket_name, target_path_in_bucket)
4. Upload large files(上传大文件)
在上传、下载或复制文件或 S3 对象时,适用于 Python 的 AWS 开发工具包会自动管理重试以及multipart 和非multipart 传输。 通过使用非常适合大多数场景的合理默认设置来执行管理操作。 为了处理特殊情况,可以配置默认设置以满足要求。
# using simple upload
self.client.upload_file(local_file_path, bucket_name, target_path_in_bucket)# using multi-part upload to extend size limitation
GB = 1024 ** 3
config = TransferConfig(multipart_threshold=5*GB)
self.client.upload_file(local_file_path, bucket_name, target_path_in_bucket, Config=config)
速度对比:
Test file | Default upload | Specified multi-part upload |
2GB | 221MB/s | 150~212MB/s |
13GB | 232MB/s | 224~240MB/s |
总体而言,自行配置的速度不一定比默认自适应的速度高,而高也高不到哪里去。
5. Download files(下载)
# download single file
self.client.download_file(bucket_name, target_path_in_bucket, local_file_path)# download single file as object
with open('FILE_NAME', 'wb') as f: # binary mode onlys3.download_fileobj('BUCKET_NAME', 'OBJECT_NAME', f)# download folder
list_objects_v2() -> download_file()
6. Delete files in buckets(删除)
self.client.delete_object(Bucket=bucket_name, Key=target_path_in_bucket)
7. Using Calback as ProgressBar(监控进度条)
使用进度条来监控操作状态。
示例来自 Uploading files ‒ Boto3 Docs 1.24.25 documentation 和 How can I increase my AWS s3 upload speed when using boto3?
方法一:官方示例,速度程序运行降速80%!
import threadingclass ProgressPercentage(object):def __init__(self, filename):self._filename = filenameself._size = float(os.path.getsize(filename))self._seen_so_far = 0self._lock = threading.Lock()def __call__(self, bytes_amount):# To simplify, assume this is hooked up to a single filenamewith self._lock:self._seen_so_far += bytes_amountpercentage = (self._seen_so_far / self._size) * 100sys.stdout.write("\r%s %s / %s (%.2f%%)" % (self._filename, self._seen_so_far, self._size,percentage))sys.stdout.flush()s3.upload_file('FILE_NAME', 'BUCKET_NAME', 'OBJECT_NAME',Callback=ProgressPercentage('FILE_NAME'))
方法二:民间示例,程序运行降速10%
from tqdm import tqdm
import boto3.s3.transfer as s3transferclass Tool():def __init__():passdef client_upload_files(self, bucket, local_path, aws_path, progress_func):transfer_config = s3transfer.TransferConfig(use_threads=True,max_concurrency=10,)s3t = s3transfer.create_transfer_manager(self.client, transfer_config)s3t.upload(local_path, bucket, aws_path, subscribers=[s3transfer.ProgressCallbackInvoker(progress_func),])s3t.shutdown()with tqdm(desc='upload', ncols=60,total=totalsize, unit='B', unit_scale=1) as pbar:tool.client_upload_files(bucket_name, large_file, large_target_file, pbar.update)
实验(坑)
aws的操作其实是非常繁琐的,因为它基本上很多事情都存在多种实现,而作为初学者难以判断这些实现有哪些坑,以下列举几个基本问题:
- 为什么我无法使用session/resource/queue/DynamicDB等服务?
- 因为没有权限或没有购买相关服务
- 使用endpoint可以做什么事情?
- endpoint用于创建low-level client,是aws服务最基础的api之一,基本上client和服务是一对一的关系,所以endpoint的权限是非常基本的,这取决于创建endpoint的时候所指定的权限。
- 在实践中,client应该被call多次还是reuse?
- 事实上,这取决于aws的收费政策!目前aws仅对服务类型和条件收费,对client的call次数不收费,因此原则上recall和reuse是等价的。然而,从程序规范而言,应该reuse。
- 上传和下载有哪些关注点?
- S3对不同层次的资源调用存在速度限制,对于low-level调用存在5GB/单个文件的限制,除非通过multi-part模式处理。然而,在boto3中对此进行了优化和封装,可以自动根据处理文件的大小选择合适的模式进行上传,最多支持5TB。
- 文件的上传默认采用覆盖写。
- client处理数据的时候是线程安全的,但无法处理突变的数据,因此不应该同时对S3中的单个数据同时读写。
- 线程安全:
- 最佳策略是,认为所有类型的连接都不是线程安全的!以免出现意外的错误。
- 由于不是线程安全的,因此最好不要使用多线程,至少不要使用互相沟通的多线程,除非你对boto3的属性非常熟悉。
- 查询数据:
- 尽管S3采用了桶存储策略,但创建了一张数据表来存储所有的meta信息,因此可以使用SQL语句进行检索。
相关文章:
python botos s3 aws
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html AWS是亚马逊的云服务,其提供了非常丰富的套件,以及支持多种语言的SDK/API。本文针对其S3云储存服务的Python SDK(boto3)的使用进行介绍。 …...
python画神经网络图
代码1(画神经网络连接图) from math import cos, sin, atan import matplotlib.pyplot as plt # 注意这里并没有用到这个networkx这个库,完全是根据matploblib这个库来画的。 class Neuron():def __init__(self, x, y,radius,nameNone):self.x xself.y …...
Bash 编程精粹:从新手到高手的全面指南之逻辑控制
在 Unix 和 Linux 系统中,Bash(Bourne-Again Shell)是一种广泛使用的 shell,提供了强大的脚本编程能力。本文将详细介绍 Bash 脚本中的逻辑控制结构,包括条件判断、分支选择、循环控制以及退出控制等内容。 条件判断&…...
自动化运维(三十)Ansible 实战之自定义插件
Ansible 自定义插件允许你扩展其功能,以满足特定的自动化需求。Ansible 支持多种类型的插件开发,如动态库存、查找、回调、过滤器、变量等。这里我们将通过实例,介绍如何开发、部署和使用一个自定义插件。 开发自定义查找插件 查找插件用于在 Ansible 任务中动态获取数据。…...
实习僧网站的实习岗位信息分析
目录 背景描述数据说明数据集来源问题描述分析目标以及导入模块1. 数据导入2. 数据基本信息和基本处理3. 数据处理3.1 新建data_clean数据框3.2 数值型数据处理3.2.1 “auth_capital”(注册资本)3.2.2 “day_per_week”(每周工作天数…...
C语言中局部变量和全局变量是否可以重名?为什么?
可以重名 在C语言中, 局部变量指的是定义在函数内的变量, 全局变量指的是定义在函数外的变量 他们在程序中的使用方法是不同的, 当重名时, 局部变量在其所在的作用域内具有更高的优先级, 会覆盖或者说隐藏同名的全局变量 具体来说: 局部变量的生命周期只在函数内部,如果出了…...
小程序中配置scss
找到:project.config.json 文件 setting 模块下添加: "useCompilerPlugins": ["sass","其他的样式类型"] 配置完成后,重启开发工具,并新建文件 结果:...
ZYNQ-Vitis(SDK)裸机开发之(四)PS端MIO和EMIO的使用
目录 一、ZYNQ中MIO和EMIO简介 二、Vivado中搭建block design 1.配置PS端MIO: 2.配置PS端EMIO: 三、Vitis中新建工程进行GPIO控制 1. GPIO操作头文件gpio_hdl.h: 2.GPIO操作源文件gpio_hdl.c: 3.main函数进行调用 例程开发…...
聊聊jvm中内存模型的坑
jvm线程的内存模型 看图,简单来说线程中操作的变量是副本。在并发情况下,如果数据发生变更,副本的数据就变为脏数据。这个时候就会有并发问题。 参考:https://www.cnblogs.com/yeyang/p/12580682.html 怎么解决并发问题 解决的…...
DevOps已死?2024年的DevOps将如何发展
随着我们进入2024年,DevOps也发生了变化。新兴的技术、变化的需求和发展的方法正在重新定义有效实施DevOps实践。 IDC预测显示,未来五年,支持DevOps实践的产品市场继续保持健康且快速增长,2022年-2027年的复合年增长率࿰…...
appium控制手机一直从下往上滑动
用于使用Appium和Selenium WebDriver在Android设备上滚动设置应用程序的界面。具体来说,它通过WebDriverWait和expected_conditions等待元素出现,然后使用ActionChains移动到该元素并执行滚动动作。在setUp中,它初始化了Appium的WebDriver和c…...
为什么光伏探勘测绘需要无人机?
随着全球对可再生能源需求的不断增长,光伏产业也迎来了快速发展的机遇。光伏电站作为太阳能发电的主要形式之一,其建设前期的探勘测绘工作至关重要。在这一过程中,无人机技术的应用正逐渐展现出其独特的优势。那么,为什么光伏探勘…...
day10 | 栈与队列 part-2 (Go) | 20 有效的括号、1047 删除字符串中的所有相邻重复项、150 逆波兰表达式求值
今日任务 20 有效的括号 (题目: . - 力扣(LeetCode))1047 删除字符串中的所有相邻重复项 (题目: . - 力扣(LeetCode))150 逆波兰表达式求值 (题目: . - 力扣(LeetCode)) 20 有效的括号 题目: . - 力扣&…...
深入解析Tomcat的工作流程
tomcat解析 Tomcat是一个广泛使用的开源Servlet容器,用于托管Java Web应用程序。理解Tomcat的工作流程对于开发人员和系统管理员来说是非常重要的。本文将深入探讨Tomcat的工作原理,包括请求处理、线程池管理、类加载、以及与Web服务器之间的通信。 ###…...
【web网页制作】html+css旅游家乡山西主题网页制作(3页面)【附源码】
山西旅游网页目录 涉及知识写在前面一、网页主题二、网页效果Page1、景点介绍Page2、酒店精选|出行攻略Page3、景色欣赏 三、网页架构与技术3.1 脑海构思3.2 整体布局3.3 技术说明书 四、网页源码4.1 主页模块源码4.2 源码获取方式 作者寄语 涉及知识 山西旅游主题网页制作&am…...
系统参数指标:QPS、TPS、PV、UV等
QPS QPS:Queries Per Second 是每秒查询率,是一台服务器每秒能够相应的查询次数,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,即每秒的响应请求数,也即是最大吞吐能力。 TPS TPS:Tra…...
一入鸿蒙深似海,从此Spring是路人:鸿蒙开发面试题
详细内容请参考最新的官方鸿蒙文档,不保证时效性 写得不对的地方请多多指点,本文仅代表个人所学知识范围 联系方式QQ 1219723557,可一同交流学习 欢迎补充,希望能做一个汇总版本出来 1. 网络编程基本知识(较为简单&…...
【Python】使用OPC UA创建数据服务器
目录 准备工作服务器设置创建或获取节点设置节点值启动服务器查看服务器客户端总结 在工业自动化和物联网(IoT)领域,OPC UA(开放平台通信统一架构)已经成为一种广泛采用的数据交换标准。它提供了一种安全、可靠且独立于…...
JavaScript(六)-高级篇
文章目录 作用域局部作用域全局作用域作用域链JS垃圾回收机制闭包变量提升 函数进阶函数提升函数参数动态参数多余参数 箭头函数 解构赋值数组解构对象解构 遍历数组forEach方法(重点)构造函数深入对象创建对象的三种方式构造函数实例成员 & 静态成员…...
速盾:游戏cdn什么意思
CDN(Content Delivery Network)是指内容分发网络,它是由一组位于世界各地的服务器组成的网络,用于将内容有效地传输给用户。游戏CDN,顾名思义,就是用于游戏内容分发的网络。 在传统的网络传输模式中&#…...
数据库-Redis(11)
目录 51.什么是Redis事务? 52.Redis事务相关命令? 53.Redis事务的三个阶段?...
【网安小白成长之路】6.pikachu、sql-labs、upload-labs靶场搭建
🐮博主syst1m 带你 acquire knowledge! ✨博客首页——syst1m的博客💘 🔞 《网安小白成长之路(我要变成大佬😎!!)》真实小白学习历程,手把手带你一起从入门到入狱🚭 &…...
(七)C++自制植物大战僵尸游戏关卡数据加载代码讲解
植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/xjvbb 打开LevelData.h和LevelData.cpp文件。文件位置如下图所示。 LevelData.h 此头文件中定义了两个类,分别是OpenLevelData、LevelData,其中OpenLevelData用于加载文件数据。LevelData解析数据…...
wpf下RTSP|RTMP播放器两种渲染模式实现
技术背景 在这篇blog之前,我提到了wpf下播放RTMP和RTSP渲染的两种方式,一种是通过控件模式,另外一种是直接原生RTSP、RTMP播放模块,回调rgb,然后在wpf下渲染,本文就两种方式做个说明。 技术实现 以大牛直…...
Element-UI 自定义-下拉框选择年份
1.实现效果 场景表达: 默认展示当年的年份,默认展示前7年的年份 2.实现思路 创建一个新的Vue组件。 使用<select>元素和v-for指令来渲染年份下拉列表。 使用v-model来绑定选中的年份值。 3.实现代码展示 <template><div><el-…...
二叉树的链式存储
二叉树是一种非常重要的数据结构,它能够高效地进行数据的插入、删除和查找操作。二叉树的每个节点最多有两个子节点,分别是左子节点和右子节点。二叉树可以采用多种不同的存储方式来实现,其中链式存储是最为直观和常用的一种方法。本文将深入…...
[计算机效率] 鼠标手势工具:WGestures(解放键盘的超级效率工具)
3.22 鼠标手势工具:WGestures 通过设置各种鼠标手势和操作进行绑定。当用户通过鼠标绘制出特定的鼠标手势后就会触发已经设置好的操作。有点像浏览器中的鼠标手势,通过鼠标手势操纵浏览器做一些特定的动作。这是一款强大的鼠标手势工具,可以…...
Linux useradd命令教程:如何创建新的用户账户(附实例详解和注意事项)
Linux useradd命令介绍 useradd是Linux中用于添加用户账户的命令。它可以用于创建新的用户,并可以配合不同的选项来指定用户的主目录、UID、GID、组等信息。 Linux useradd命令适用的Linux版本 useradd命令在大多数Linux发行版中都可以使用,包括但不限…...
基于ollama搭建本地chatGPT
ollama帮助我们可以快速在本地运行一个大模型,再整合一个可视化页面就能构建一个chatGPT,可视化页面我选择了chat-ollama(因为它还能支持知识库,可玩性更高),如果只是为了聊天更推荐chatbox 部署步骤 下载…...
C++11 数据结构3 线性表的循环链式存储,实现,测试
上一节课,我们学了线性表 单向存储结构(也就是单链表),这个是企业常用的技术,且是后面各种的基本,一定要牢牢掌握,如果没有掌握,下面的课程会云里雾里。 一 ,循环链表 1…...
中卫网站建设哪家好/搜索引擎营销的概念及特点
之前我遇到过这样的需求,要求在ListView中按时间对数据分栏,当时的做法是在每个ListView的item中加入时间栏的布局,然后在代码中控制时间栏 的显示与隐藏。 但其实重写Adapter两个方法后就可以完成这个任务,当ListView中带有不同布…...
wordpress常规地址改错了怎么办/中囯军事网
一、单选题1、计算机中所有的数据都是用(C)数来表示A八进制B十六进制C二进制D十进制2、第二代电子计算机采用(B)作为主要器件A电子管B晶体管C小规模集成电路D大规模及和电路3、计算机语言可分为机器语言,(C)和高级语言AC语言BBasic语言C汇编语言DPASCAL语言4、计算机…...
化妆品网站建设策划书/郑州网站策划
很多朋友想开始用手机拍视频,可能不知道如何剪辑!本文将给大家介绍几款好用又方便的手机剪辑短视频工具,即便是零基础,用下面这些工具,你就可以轻松开始剪辑短视频。选择一款实用好用的剪辑工具很重要,工具…...
如何在网站中做公示信息/下载百度网盘app最新版
接上篇。。。 4. 可空属性&默认值&忽略属性 默认情况下, 属性值可空, 如果强制要求某个属性非空, 可以使用如下方法: 遵循协议方法 (NSArray *)requiredProperties { return ["name"]; } 特点:如果再次赋值为nil, 则会抛出异常错误 也…...
广 做网站蓝光电影下载/免费发布软文广告推广平台
# qt5模式才有交互效果 %matplotlib qt5 import matplotlib.pyplot as plt import numpy as np # 解决汉字乱码 import matplotlib as mpl # 字体会按照列表依次从电脑中查找,直到找到 plt.rcParams[font.family] [Arial Unicode MS,Microsoft YaHei,SimHei,sans-serif] plt.r…...
建设网站流程/合肥百度快速排名提升
本章内容: 1. PL/SQL的历史和背景 2. Oracle开发架构 知识点: 1. SQL和PL/SQL的关系: The SQL language is the interface to the Oracle Database 12c database engine, and Oracle extensions provide a competitive advantage. The PL…...