This is the blog section. It has two categories: News and Releases.
Files in these directories will be listed in reverse chronological order.
This is the blog section. It has two categories: News and Releases.
Files in these directories will be listed in reverse chronological order.
安装pip install django - simpleui
修改bookpro\settings.py 中 INSTALLED_APPS
1INSTALLED_APPS = [
2 # ...
3 'simpleui',
4 # ...
5]
重启登录后台, 就可以看到变化
数据库配置字段中 ENGING 常用可选配置为: ‘django.db.backends.sqlite3’,‘django.db.backends.postgresql’,‘django.db.backends.mysql’,或 ‘django.db.backends.oracle’
选择 ‘django.db.backends.sqlite3’ 时 NAME 为 数据库文件路径
1DATABASES = {
2 'default': {
3 'ENGINE': 'django.db.backends.sqlite3',
4 'NAME': BASE_DIR / 'db.sqlite3',
5 }
6}
选择 ‘django.db.backends.postgresql’,‘django.db.backends.mysql’,或 ‘django.db.backends.oracle’ NAME 数据库名称 USER / PASSWORD 数据库用户名及口令 HOST / PORT 数据库地址及端口
1DATABASES = {
2 'default': {
3 'ENGINE': 'django.db.backends.mysql',
4 'NAME': 'mydatabase',
5 'USER': 'mydatabaseuser',
6 'PASSWORD': 'mypassword',
7 'HOST': '127.0.0.1',
8 'PORT': '3306',
9 }
10}
使用Mysql时
1# 在文件中增加
2import pymysql
3pymysql.install_as_MySQLdb()
模型都是一个 Python 的类,这些类继承 django.db.models.Model 每个属性都相当于一个数据库的字段 django.db.models.Field 的子类
AutoField: integer AUTO_INCREMENT BigAutoField: bigint AUTO_INCREMENT BinaryField: longblob BooleanField: bool CharField: varchar( % (max_length)s) CommaSeparatedIntegerField: varchar( % (max_length)s) DateField: date DateTimeField: datetime DecimalField: numeric(% (max_digits)s % (decimal_places)s) DurationField: bigint FileField: varchar( % (max_length)s) FilePathField: varchar( % (max_length)s) FloatField: double precision IntegerField: integer BigIntegerField: bigint IPAddressField: char(15) GenericIPAddressField: char(39) NullBooleanField: bool OneToOneField: integer PositiveIntegerField: integer UNSIGNED PositiveSmallIntegerField: smallint UNSIGNED SlugField: varchar( % (max_length)s) SmallIntegerField: smallint TextField: longtext TimeField: time UUIDField: char(32)
公共参数 null 数据库中字段是否可以为空 db_column 数据库中字段的列名 default 数据库中字段的默认值 primary_key 数据库中字段是否为主键,也是索引,加速查找,列值唯一且不能为空 db_index 数据库中字段是否可以建立索引,只能加速查找 unique 数据库中字段是否可以建立唯一索引,可加速查找,限制列值唯一 unique_for_date 数据库中字段【日期】部分是否可以建立唯一索引 unique_for_month 数据库中字段【月】部分是否可以建立唯一索引 unique_for_year 数据库中字段【年】部分是否可以建立唯一索引
python manage.py startapp polls
修改 bookpro/settings.py
1# 添加自己新建的应用
2INSTALLED_APPS = [
3 'polls',
4
5]
通常, INSTALLED_APPS 默认包括了以下 Django 的自带应用:
django.contrib.admin – 管理员站点, 你很快就会使用它。 django.contrib.auth – 认证授权系统。 django.contrib.contenttypes – 内容类型框架。 django.contrib.sessions – 会话框架。 django.contrib.messages – 消息框架。 django.contrib.staticfiles – 管理静态文件的框架。 这些应用被默认启用是为了给常规项目提供方便。
在polls目录中 新建文件 urls.py
内容
1# 引入
2from django.urls import path, include
3from . import views
4
5# 建立路径
6urlpatterns = [
7 # 请求路径 path("路径字段", 处理函数, 别名)
8 path("", views.index, name="index"),
9 path("info", views.infofun, name='info'),
10]
在 bookpro/urls.py 中添加对polls的路径引用
1from django.urls import path, include
2
3urlpatterns = [
4 path('polls/', include('polls.urls')),
5 path('admin/', admin.site.urls),
6]
在polls/views.py中
1from django.http import HttpResponse
2# Create your views here.
3
4
5def index(request):
6 return HttpResponse("hello index")
7
8
9def infofun(request):
10 return HttpResponse("hello infofun")
在polls/models.py中
1from django.db import models
2
3
4class Question(models.Model):
5 question_text = models.CharField(max_length=200)
6 pub_date = models.DateTimeField('date published')
7
8
9class Choice(models.Model):
10 question = models.ForeignKey(Question, on_delete=models.CASCADE)
11 choice_text = models.CharField(max_length=200)
12 votes = models.IntegerField(default=0)
然后迁移至数据库中
1python manage.py makemigrations
2python manage.py migrate
在polls/admin.py中
1from django.contrib import admin
2
3# Register your models here.
4from . import models
5
6admin.site.register(models.Question)
7admin.site.register(models.Choice)
重启或刷新浏览器访问
找一个英文路径的空目录下
django-admin startporject bookpro
修改 bookpro/bookpro/setting.py 配置文件
1
2# 允许任意IP访问
3ALLOWED_HOSTS = ['*', ]
4
5# 修改 语言及时区
6LANGUAGE_CODE = 'zh-hans'
7TIME_ZONE = 'Asia/Shanghai'
8
9# 配置日志
10import time
11LOGGING = {
12 'version': 1,
13 'disable_existing_loggers': False,
14 'formatters': {
15 'standard': {
16 'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s'
17 },
18 'verbose': {
19 'format': '{asctime} {levelname} {filename}:{lineno} {module}{funcName} {process:d} {thread:d} {message}',
20 'style': '{',
21 },
22 'simple': {
23 'format': '{levelname} {message}',
24 'style': '{',
25 },
26 },
27 'filters': {
28 'require_debug_false': {
29 '()': 'django.utils.log.RequireDebugFalse',
30 },
31 'require_debug_true': {
32 '()': 'django.utils.log.RequireDebugTrue',
33 },
34 },
35 'handlers': {
36 # 默认记录所有日志
37 'default': {
38 'level': 'INFO',
39 'class': 'logging.handlers.RotatingFileHandler',
40 'filename': BASE_DIR / 'all-{}.log'.format(time.strftime('%Y-%m-%d')),
41 'maxBytes': 1024 * 1024 * 5, # 文件大小
42 'backupCount': 5, # 备份数
43 'formatter': 'verbose', # 输出格式
44 'encoding': 'utf-8', # 设置默认编码,否则打印出来汉字乱码
45 },
46 # 输出错误日志
47 'error': {
48 'level': 'ERROR',
49 'class': 'logging.handlers.RotatingFileHandler',
50 'filename': BASE_DIR / 'error-{}.log'.format(time.strftime('%Y-%m-%d')),
51 'maxBytes': 1024 * 1024 * 5, # 文件大小
52 'backupCount': 5, # 备份数
53 'formatter': 'verbose', # 输出格式
54 'encoding': 'utf-8', # 设置默认编码
55 },
56 # 控制台输出
57 'console': {
58 'level': 'DEBUG',
59 'filters': ['require_debug_true'],
60 'class': 'logging.StreamHandler',
61 'formatter': 'verbose'
62 },
63 # 输出info日志
64 'info': {
65 'level': 'INFO',
66 'class': 'logging.handlers.RotatingFileHandler',
67 'filename': BASE_DIR / 'info-{}.log'.format(time.strftime('%Y-%m-%d')),
68 'maxBytes': 1024 * 1024 * 5,
69 'backupCount': 5,
70 'formatter': 'verbose',
71 'encoding': 'utf-8', # 设置默认编码
72 },
73 },
74 'loggers': {
75 # 类型 为 django 处理所有类型的日志, 默认调用
76 'django': {
77 'handlers': ['default', 'console'],
78 'level': 'INFO',
79 'propagate': False
80 },
81 'django.request': {
82 'handlers': ['error'],
83 'level': 'ERROR',
84 'propagate': False,
85 },
86 }
87}
python manage.py runserver
此时打开浏览器访问http://127.0.0.1:9000/ 即可看到启动页面
1# 生成模型对应的数据库语句
2python manage.py makemigrations
3
4# 将改动迁移到数据库中
5python manage.py migrate
6
7# 建立超级用户
8python manage.py createsuperuser
重启或刷新浏览器访问 http://127.0.0.1:9000/admin/ 即可登录后台
注意: 最新版grappelli支持到django3.2
pip install django-grappelli
# 项目的setting文件中
INSTALLED_APPS = [
'grappelli',
...
]
GRAPPELLI_ADMIN_TITLE = "管理后台"
STATIC_ROOT = BASE_DIR / 'static'
然后运行静态资源收集
python manage.py collectstatic
收工, 搞定
docker核心组件如下:docker客户端与服务器、docker镜像、registry、docker容器。对它们详细描述如下:
客户端与服务器
docker是一个c/s架构的程序,docker客户端需要向docker服务器或者守护进程发出请求。服务器或者守护进程完成工作并且返回结果。docker提供了命令行docker和restful api,可以使用他们连接本地或者远程的守护进程。
docker架构
镜像
镜像是docker世界的基石,用户基于镜像可以构建容器。
registry
docker使用registry保存用户镜像。Registry分为共有和私有两种,Docker官方registry为Docker Hub。
容器
容器基于镜像启动,里面可以运行一个或者多个进程。
1# 安装
2yum install docker
3# 启动并配置自启动
4service docker start
5chkconfig docker on
6
7# Centos 新语法
8systemctl start docker.service
9systemctl enable docker.service
10
11# 配置docker加速
12vi /etc/docker/daemon.json
13#添加后
14{
15 "registry-mirrors": ["https://registry.docker-cn.com"],
16 "live-restore": true
17}
1# 拉取镜像
2docker pull image_name
3# 查看主机已有镜像
4docker images
5# 删除镜像
6docker rmi docker.io/tomcat:7.0.77-jre7
7docker rmi b39c68b7af30
8# 查看正在运行的容器
9docker ps
10# 查看所有容器
11docker ps -a
12# 启动,停止,重启容器
13docker start container_name/container_id
14docker stop container_name/container_id
15docker restart container_name/container_id
16# 后台启动容器后想要进入
17docker attach container_name/container_id
18# 删除容器
19docker rm container_name/container_id
Flask的基础认识
Flask 本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login,数据库Flask-SQLAlchemy), 都需要用第三方的扩展来实现。比如可以用 Flask 扩展加入ORM、窗体验证工具,文件上传、身份验证等。 Flask 没有默认使用的数据库,你可以选择 MySQL,也可以用 NoSQL
当安装 Flask 时,以下配套软件会被自动安装。 Werkzeug 用于实现 WSGI ,应用和服务之间的标准 Python 接口。 Jinja 用于渲染页面的模板语言。 MarkupSafe 与 Jinja 共用,在渲染页面时用于避免不可信的输入,防止注 入攻击。 ItsDangerous 保证数据完整性的安全标志数据,用于保护 Flask 的 session cookie. Click 是一个命令行应用的框架。用于提供 flask 命令,并允许添加 自定义管理命令。 Blinker 提供对于 信号 的支持。
pip install fastapi uvicorn gunicorn supervisor
1
2import uvicorn
3from loguru import logger
4import arrow
5import pymysql
6import sys
7
8from fastapi import FastAPI, Query, Request, Body
9from pydantic import BaseModel
10from fastapi.encoders import jsonable_encoder
11from fastapi.responses import JSONResponse
12from typing import List, Tuple, Set
13
14
15app = FastAPI(title='订单同步接口', description='订单同步接口')
16
17if "win" in sys.platform:
18 logger.add("./db.log", encoding='utf-8')
19else:
20 logger.add("/path/db.log", encoding='utf-8')
21
22
23curnow = arrow.now()
24nowhour = curnow.format("YYYY-MM-DD HH:mm:ss")
25before3hour = curnow.shift(hours=-3).format("YYYY-MM-DD HH:mm:ss")
26
27
28class Argcls(BaseModel):
29 begintime: str = before3hour
30 endtime: str = nowhour
31 orders: List[str] = []
32
33class DB:
34
35 def __init__(self):
36 try:
37 if "win" in sys.platform:
38 self.db = pymysql.connect(host="127.0.0.1", port=3306, user="root", password="root", db="dbname", charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
39 else:
40 self.db = pymysql.connect(host="127.0.0.1", port=3306, user="root", password="root", db="dbname", charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor)
41 except:
42 logger.error("数据库连接失败!")
43 self.cur = self.db.cursor()
44
45 def query(self, sql):
46 self.cur.execute(sql)
47 return self.cur.fetchall()
48
49 def __del__(self):
50 self.cur.close()
51 self.db.close()
52
53
54
55sql_order = """ select * from user_order where states>0 and %s """
56
57sql_order_subs = """ SELECT * FROM user_order_subs WHERE orders_id='%s'"""
58
59@app.post('/getOrder', summary='指定时间范围内的订单', description='查询指定时间范围内的订单')
60def seach_order(args: Argcls = Body(..., example={"begintime": "查询订单的开始时间 eg 2022-03-04 00:00:00",
61 "endtime": "查询订单的结束时间 eg 2022-03-04 23:59:59",
62 "orders": "List[orderid字符串]"})):
63
64 logger.info("查询参数 {}", args)
65
66 wherestr = "create_time>='%s' and create_time<='%s'" % (args.begintime, args.endtime)
67 if len(args.orders):
68 orderstr = " orders_codes in ('%s')" % "','".join(args.orders)
69 wherestr = "( (%s) or %s)" % (wherestr, orderstr)
70
71 sql = sql_order % (wherestr)
72 logger.info("查询语句 {}", sql)
73
74 db = DB()
75
76 res = db.query(sql)
77 for key, row in enumerate(res):
78 res[key]['sub_orders'] = db.query(sql_order_subs % (row['id']))
79
80 logger.info("返回条数 {}", len(res))
81 return res
82
83
84if __name__ == '__main__':
85 logger.info("启动运行...")
86 uvicorn.run(app='main:app', host="0.0.0.0", port=7296, reload=True, debug=True)
# 命令行运行测试
python main.py
# 使用 uvicron 运行
uvicorn main:app --reload --host 0.0.0.0 --port 7296
# 使用 gunicorn 运行
gunicorn main:app -b 0.0.0.0:7296 -w 4 -k uvicorn.workers.UvicornWorker --daemon
* 以配置文件的方式启动
gunicorn.conf
import multiprocessing
# 并行工作进程数(multiprocessing.cpu_count()线程数,官方说可以有:核心数*2+1个)
workers = multiprocessing.cpu_count() * 2 + 1
# 指定每个工作者的线程数
threads = 2
# 监听内网端口5000
bind = '127.0.0.1:5000'
# 设置守护进程,推荐将进程交给supervisor管理(以守护进程形式来运行Gunicorn进程,true其实就是将这个服务放到后台去运行,故此处设置false,交给supervisor开守护进程,因为supervisor不支持后台进程)
daemon = 'false'
# 工作模式协程
worker_class = 'gevent'
# 设置最大并发量
worker_connections = 2000
# 设置进程文件目录
pidfile = '/var/run/gunicorn.pid'
# 设置访问日志和错误信息日志路径
accesslog = '/var/log/gunicorn_acess.log'
errorlog = '/var/log/gunicorn_error.log'
# 日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
loglevel = 'warning'
# 启动unicorn
gunicorn -c gunicorn.conf main:app
# 获取Gunicorn进程树
pstree -ap|grep gunicorn
# 重启Gunicorn任务
kill -HUP 30080
pip install supervisor
默认配置文件:/etc/supervisord.conf
进程管理配置文件放到:/etc/supervisord.d/目录下即可
mkdir -p ~/etc/supervisor/conf.d
mkdir -p ~/etc/supervisor/var/log
cd ~/etc
echo_supervisord_conf > supervisord.conf
* 修改 supervisor.conf,让 Supervisor 进程产生的一些文件生成到上面我们创建的目录下,而不是其默认指定的地方。
* 首先找到 [unix_http_server] 版块,将 file 设置改为如下的值,即让 socket 文件生成在 ~/etc/supervisor/var/ 目录下。
注意 supervisor 不支持将 ~ 展开为用户 home 目录,所以要用绝对路径指定。:
* [unix_http_server]file=/root/etc/supervisor/var/supervisor.sock
* 类似的修改 [supervisord] 板块下的 logfile 和 pidfile 文件的路径,还有 user 改为系统用户,这样 supervisor 启动的进程将以系统用户运行,避免可能的权限问题:
*
[supervisord]logfile= /root/etc/supervisor/var/log/supervisord.log
pidfile=/root/etc/supervisor/var/supervisord.pid
user=root
* [supervisorctl] 板块下:
* [supervisorctl]serverurl=unix:///root/etc/supervisor/var/supervisor.sock
* [include] 版块,将 /home/yangxg/etc/supervisor/conf.d/ 目录下所有以 .ini 结尾的文件内容包含到配置中来,
这样便于配置的模块化管理,和之前 Nginx 配置文件的处理方式是类似的。
* [include]files = /root/etc/supervisor/conf.d/*.ini
* 然后我们到 conf.d 新建应用的配置
(py3.6) [root@iZbp11gqesu0znu7pkmgp7Z conf.d]# cat fig1.ini
[program:api-fastapi]
command=gunicorn main:app -w 4 -k uvicorn.workers.UvicornWorker --timeout 30 -b 0.0.0.0:8000
directory=/root/api-fastapi/
autostart=true
autorestart=unexpected
user=root
stdout_logfile=/etc/supervisor/var/log/api-fastapi-stdout.log
stderr_logfile=/etc/supervisor/var/log/api-fastapi-stderr.log
各项配置的含义:
[program:wenda_slmx] 指明运行应用的进程,名为 wenda_slmx。
command 为进程启动时执行的命令。
directory 指定执行命令时所在的目录。
autostart 随 Supervisor 启动自动启动进程。
autorestart 进程意外退出时重启。
user 进程运行的用户,防止权限问题。
stdout_logfile,stderr_logfile 日志输出文件。
* 启动 Supervisor
supervisord -c ~/etc/supervisord.conf
* -c 指定 Supervisr 启动时的配置文件。
* 更新新的配置到supervisord
* supervisorctl update
* 重新启动配置中的所有程序
* supervisorctl reload
* 浏览器输入域名,可以看到服务已经正常启动了。
[unix_http_server]
file=/tmp/supervisor.sock ;UNIX socket 文件,supervisorctl 会使用
;chmod=0700 ;socket文件的mode,默认是0700;chown=nobody:nogroup ;socket文件的owner,格式:uid:gid
;[inet_http_server] ;HTTP服务器,提供web管理界面
;port=127.0.0.1:9001 ;Web管理后台运行的IP和端口,如果开放到公网,需要注意安全性
;username=user ;登录管理后台的用户名
;password=123 ;登录管理后台的密码
[supervisord]
logfile=/tmp/supervisord.log ;日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB ;日志文件大小,超出会rotate,默认 50MB,如果设成0,表示不限制大小
logfile_backups=10 ;日志文件保留备份数量默认10,设为0表示不备份
loglevel=info ;日志级别,默认info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ;pid 文件
nodaemon=false ;是否在前台启动,默认是false,即以 daemon 的方式启动
minfds=1024 ;可以打开的文件描述符的最小值,默认 1024
minprocs=200 ;可以打开的进程数的最小值,默认 200
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ;通过UNIX socket连接supervisord,路径与unix_http_server部分的file一致;serverurl=http://127.0.0.1:9001 ; 通过HTTP的方式连接supervisord
; [program:xx]是被管理的进程配置参数,xx是进程的名称
[program:xx]
command=/opt/apache-tomcat-8.0.35/bin/catalina.sh run ; 程序启动命令
autostart=true ; 在supervisord启动的时候也自动启动
startsecs=10 ; 启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒
autorestart=true ; 程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启
startretries=3 ; 启动失败自动重试次数,默认是3
user=tomcat ; 用哪个用户启动进程,默认是root
priority=999 ; 进程启动优先级,默认999,值小的优先启动
redirect_stderr=true ; 把stderr重定向到stdout,默认false
stdout_logfile_maxbytes=20MB ; stdout 日志文件大小,默认50MB
stdout_logfile_backups = 20 ; stdout 日志文件备份数,默认是10; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out
stopasgroup=false ;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程
killasgroup=false ;默认为false,向进程组发送kill信号,包括子进程
;包含其它配置文件
[include]
files = relative/directory/*.ini ;可以指定一个或多个以.ini结束的配置文件
子进程配置文件说明:
给需要管理的子进程(程序)编写一个配置文件,放在/etc/supervisor.d/目录下,以.ini作为扩展名(每个进程的配置文件都可以单独分拆也可以把相关的脚本放一起)。如任意定义一个和脚本相关的项目名称的选项组
#项目名[program:blog]#脚本目录
directory=/opt/bin
#脚本执行命令
command=/usr/bin/python /opt/bin/test.py
#supervisor启动的时候是否随着同时启动,默认True
autostart=true#当程序exit的时候,这个program不会自动重启,默认unexpected,设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected和true。如果为false的时候,无论什么情况下,都不会被重新启动,如果为unexpected,只有当进程的退出码不在下面的exitcodes里面定义的
autorestart=false#这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了。默认值为1
startsecs=1
#脚本运行的用户身份
user = test
#日志输出
stderr_logfile=/tmp/blog_stderr.log
stdout_logfile=/tmp/blog_stdout.log
#把stderr重定向到stdout,默认 false
redirect_stderr = true#stdout日志文件大小,默认 50MB
stdout_logfile_maxbytes = 20MB
#stdout日志文件备份数
stdout_logfile_backups = 20
子进程配置示例:
#说明同上
[program:test]
directory=/opt/bin
command=/opt/bin/test
autostart=true
autorestart=false
stderr_logfile=/tmp/test_stderr.log
stdout_logfile=/tmp/test_stdout.log
#user = test
supervisorctl status //查看所有进程的状态
supervisorctl stop es //停止es
supervisorctl start es //启动es
supervisorctl restart //重启es
supervisorctl update //配置文件修改后使用该命令加载新的配置
supervisorctl reload //重新启动配置中的所有程序
新建文件supervisord.service
#supervisord.service
[Unit]
Description=Supervisor daemon
[Service]
Type=forking
ExecStart=/usr/bin/supervisord -c /etc/supervisord.conf
ExecStop=/usr/bin/supervisorctl shutdown
ExecReload=/usr/bin/supervisorctl reload
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
------------------------------------------
cp supervisord.service /usr/lib/systemd/system/
启动服务
systemctl enable supervisord
验证一下是否为开机启动
systemctl is-enabled supervisord
git 自用配置 定义了一些常用的git简写命令
1[push]
2 default = current
3 autoSetupRemote = true
4[core]
5 safecrlf = false
6 trustctime = false
7 editor = vim
8 filemode = false
9 autocrlf = input
10 quotepath = false
11 whitespace = cr-at-eol
12 ignorecase = false
13
14[color]
15 ui = true
16 status = auto
17 diff = auto
18 branch = auto
19 interactive = auto
20[merge]
21 tool = vimdiff
22[mergetool]
23 keeptemporaries = false
24 keepbackups = false
25 prompt = false
26 trustexitcode = false
27[alias]
28 # 完全删除最后一次提交
29 rh = reset --hard HEAD^
30 # 从 本地仓库 中, 撤销 最后一次提交, 将 最后的提交内容 作为 索引目录 中的 改动 (撤销了 commit 操作)
31 rs = reset --soft HEAD^
32 # 从 本地仓库 中, 撤销 最后一次提交, 将 最后的提交内容 作为 工作目录 中的 改动 (撤销了 commit 和 add 操作)
33 rm = reset --mixed HEAD^
34 # 从 索引目录 中, 撤回 指定文件 到 工作目录, 保留 文件改动 (撤销了 add 操作)
35 ua = restore --staged
36 # 放弃 工作目录 中 指定文件 的更改, 接 指定文件名称
37 re = restore
38 ue = restore
39 #-----------------------------------------------------------------------------------------------------------
40 # 列表所有提交变更文件,增删情况
41 ls = log --stat
42 # 展示指定节点的详细变更信息
43 sw = show
44 last = log -1 --stat
45 cp = cherry-pick
46 ci = commit
47 st = status
48 unstage = reset HEAD --
49 # 检出
50 co = checkout
51 # 新建分支
52 cb = checkout -b
53 # 提交并添加提交信息
54 cm = commit -m
55 # 提交文件并提交信息
56 ca = commit -a -m
57 # 修改最后一次提交, 可以修改提交消息, 修改提交文件, 并替换掉最后提交的CommitID
58 cd = commit --amend
59 # 清除没有被跟踪的文件和目录
60 cf = clean -fd
61 df = diff
62 ds = diff --staged
63 dc = diff --cached
64 dh = diff HEAD
65 br = branch
66 bd = branch -d
67 bD = branch -D
68 pl = pull
69 ps = push
70 cl = clone
71 lg = log --all --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative -25
72 lst = log -15 --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=short --stat
73 ra = remote add
74 mn = merge --no-ff
75 ms = merge --squash
76 pr = pull --rebase
77 ff = fetch
78 rb = rebase
79 # 临时缓存未提交的修改
80 sh = stash
81 # 临时缓存未提交的修改, 可以写简短说明
82 sm = stash -m
83 # 弹出最后一次临时保存的未提交代码
84 sp = stash pop
85 # 列表所有保存的未提交修改
86 sl = stash list
87
88[http]
89 sslVerify = true
90 postbuffer = 524288000
91[gui]
92 encoding = utf-8
93[pull]
94 ff = only
95[format]
96 pretty = oneline
97[credential]
98 helper = store
99 autoDetectTimeout = -1
100[https]
101 postBuffer = 1048576000
102[pack]
103 windowMemory = 50m
104[http "https://github.com"]
105 proxy = socks5://127.0.0.1:1081
关于Gitea
Gitea 是一个自己托管的Git服务程序。他和GitHub, Bitbucket or Gitlab等比较类似。他是从 Gogs 发展而来
Gitea的首要目标是创建一个极易安装,运行非常快速,安装和使用体验良好的自建 Git 服务。 采用Go作为后端语言,只生成一个可执行程序即可。
并且他还支持跨平台,支持 Linux, macOS 和 Windows 以及各种架构,除了x86,amd64,还包括 ARM 和 PowerPC。
1
2# .bashrc 中 配置环境变量
3export GITEA_WORK_DIR=/var/lib/gitea/
4
5
6# 建立执行用户
7groupadd --system git
8useradd \
9 --system \
10 --shell /bin/bash \
11 --comment 'Git Version Control' \
12 --gid git \
13 --home-dir /home/git \
14 --create-home \
15 git
16
17# 建立工作路径
18mkdir -p /var/lib/gitea/{custom,data,log}
19chown -R git:git /var/lib/gitea/
20chmod -R 750 /var/lib/gitea/
21mkdir /etc/gitea
22chown root:git /etc/gitea
23chmod 770 /etc/gitea
1
2wget -O gitea https://dl.gitea.com/gitea/1.20.3/gitea-1.20.3-linux-amd64
3chmod +x gitea
4cp gitea /usr/local/bin/gitea
5
6
7# 首次运行
8su -l git
9GITEA_WORK_DIR=/var/lib/gitea/ /usr/local/bin/gitea web -c /etc/gitea/app.ini
1sudo vim /etc/systemd/system/gitea.service
1[Unit]
2Description=Gitea (Git with a cup of tea)
3After=syslog.target
4After=network.target
5
6[Service]
7# Uncomment the next line if you have repos with lots of files and get a HTTP 500 error because of that
8# LimitNOFILE=524288:524288
9RestartSec=2s
10Type=notify
11User=git
12Group=git
13WorkingDirectory=/var/lib/gitea/
14# If using Unix socket: tells systemd to create the /run/gitea folder, which will contain the gitea.sock file
15# (manually creating /run/gitea doesn't work, because it would not persist across reboots)
16#RuntimeDirectory=gitea
17ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
18Restart=always
19Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
20WatchdogSec=30s
21
22[Install]
23WantedBy=multi-user.target
1sudo systemctl enable gitea
2sudo systemctl start gitea
1git show
1git commit --amend --only -m "new message"
1git checkout HEAD^ filename
2git add -A
3git commit --amend
1# 如果没有推送, 使用一下命令, 可以保留撤销的提交变化内容
2git reset --soft HEAD@{1}
3# 如果已推送
4git revert HEAD^
5git push
1git commit --amend
1# 本地分支
2git branch -D/-d branch-name
3# 远程分支
4git push origin :branch-name
1git rm --cached filename
检出仓库: $ git clone git://github.com/origin_name/origin_name.git
查看远程仓库: $ git remote -v
添加远程仓库: $ git remote add origin_name remote_url
删除远程仓库: $ git remote rm origin_name
修改远程仓库: $ git remote set-url --push origin_name new_remote_url
拉取远程仓库: $ git pull remote_name local_name
推送远程仓库: $ git push remote_name local_name
查看本地分支: $ git branch
查看远程分支: $ git branch -r
创建本地分支: $ git branch name
注意新分支创建后不会自动切换为当前分支
切换分支: $ git checkout name
创建新分支并立即切换到新分支: $ git checkout -b name
删除分支: $ git branch -d name
-d选项只能删除已经参与了合并的分支, 对于未有合并的分支是无法删除的。
如果想强制删除一个分支, 可以使用-D选项
合并分支: $ git merge name
将名称为name的分支与当前分支合并
创建远程分支(本地分支push到远程): $ git push origin name
删除远程分支: $ git push origin :heads/name
我从master分支创建了一个own_br分支, 做了一些修改后, 使用git push origin master提交,
但是显示的结果却是Everything up-to-date, 发生问题的原因是git push origin master
在没有track远程分支的本地分支中默认提交的master分支, 因为master分支默认指向了origin master 分支,
这里要使用git push origin own_br:master 就可以把own_br推送到远程的master分支了。
如果想把本地的某个分支test提交到远程仓库, 并作为远程仓库的master分支,
或者作为另外一个名叫test的分支, 那么可以这么做。
$ git push origin test:master
提交本地test分支作为远程的master分支
好像只写这一句, 远程的github就会自动创建一个test分支
$ git push origin test:test
提交本地test分支作为远程的test分支
如果想删除远程的分支呢?类似于上面, 如果:左边的分支为空, 那么将删除:右边的远程的分支。
$ git push origin :test
刚提交到远程的test将被删除, 但是本地还会保存的, 不用担心
克隆远程指定分支
1git init
2git remote add -t br_name_local -f origin remote_origin_url
3git checkout br_name_local
Git 4个区: 工作区, 暂存区, 本地仓库, 远程仓库
对应5个状态: 未修改, 已修改, 已暂存, 已提交, 已推送
untracked状态git add filename 加入git暂存区git checkout -- filename, 撤销修改, 还原干净工作区git add filename, 将修改加入git暂存区git add . 到暂存区的文件可以通过 git reset ., 撤销add,回复到原修改,新增状态
可以通过 git reset filename, 撤销add,回复到原修改,新增状态
可以通过 git reset HEAD ., 回复到原修改,新增状态
同上的命令 git reset HEAD filename, 撤销暂存区的文件到原状态
可以通过 git commit -m "commit info" , 提交暂存区文件到本地仓库
可以通过 git reset --hard (.|filename), 撤销add操作和修改/新增操作,
彻底还原干净工作区
上面的命令等于以下两条命令:
git reset (.|filename) 撤销提交到缓存区, 这样缓存区就干净了
git checkout -- (.|filename) 撤销文件的修改, 这样工作区就干净了
对于最后一次commit, 可以通过 git commit --amend 打开最后提交信息修改
可以通过 git reset --hard HEAD^, 回退版本到上一个版本
可以通过 git reset --hard 59b1707, 返回到指定的提交版本
通过 git reflog 查看所有提交 版本信息
回退版本后, 如果再次后悔, 通过git reflog, 找到指定版本id, git reset --hard xxxxx
可以通过 git reset --hard origin/master, 利用远程的版本库,覆盖本地最后一次提交
可以通过 git push origin master , 推送本地版本到远程仓库
git reset --hard HEAD^ , 回退本地版本库到上一个版本git push -f, 强制推送一次给定一个正整数 n(1 ≤ n ≤ 30),输出外观数列的第 n 项。
注意:整数序列中的每一项将表示为一个字符串。
「外观数列」是一个整数序列,从数字 1 开始,序列中的每一项都是对前一项的描述。前五项如下:
1. 1
2. 11
3. 21
4. 1211
5. 111221
第一项是数字 1
描述前一项,这个数是 1 即 “一个 1 ”,记作 11
描述前一项,这个数是 11 即 “两个 1 ” ,记作 21
描述前一项,这个数是 21 即 “一个 2 一个 1 ” ,记作 1211
描述前一项,这个数是 1211 即 “一个 1 一个 2 两个 1 ” ,记作 111221
示例 1:
输入: 1
输出: "1"
解释:这是一个基本样例。
示例 2:
输入: 4
输出: "1211"
解释:当 n = 3 时,序列是 "21",其中我们有 "2" 和 "1" 两组,"2" 可以读作 "12",也就是出现频次 = 1 而 值 = 2;类似 "1" 可以读作 "11"。所以答案是 "12" 和 "11" 组合在一起,也就是 "1211"。
定义变量res=“1”, 当n=1时, 返回res
定义lst=[], 保存过程数据
从2-n开始循环, 每次循环 对res逐一位判断
当lst为空时, lst数组保存[1, 当前位数字]
当lst不为空时, 如果当前位数字和lst最后一个元素相等, 则lst倒数第二位+1, 不相等则 lst扩展[1, 当前位数字]
最后lst中所有元素转为字符, 并连接到一起返回
1#
2# @lc app=leetcode.cn id=38 lang=python3
3#
4# [38] 外观数列
5#
6
7# @lc code=start
8class Solution:
9 def countAndSay(self, n: int) -> str:
10 res = "1"
11 if n == 1:
12 return res
13 for i in range(2, n+1):
14 lst = []
15 for m in res:
16 if not lst:
17 lst.extend([1, m])
18 else:
19 if m == lst[-1]:
20 lst[-2] = lst[-2] + 1
21 else:
22 lst.extend([1, m])
23 res = ''.join([str(r) for r in lst])
24 return res
25# @lc code=end
18/18 cases passed (36 ms)
Your runtime beats 97.67 % of python3 submissions
Your memory usage beats 6.67 % of python3 submissions (13.7 MB)
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
示例 1:
输入: [1,3,5,6], 5
输出: 2
示例 2:
输入: [1,3,5,6], 2
输出: 1
示例 3:
输入: [1,3,5,6], 7
输出: 4
示例 4:
输入: [1,3,5,6], 0
输出: 0
二分查找
求出最小和最大索引的取整中间值, 判断该索引的value是否等于target, 如果相等返回索引位置
如果value大于target, 则查找的目标在中间索引值左侧, 将现在的最大索引值重置为中间值
如果value小于target, 则查找的目标在中间索引值右侧, 将现在的最小索引值重置为中间值
重新取中间索引值继续比较, 直到找到或找不到退出
则元素应该插入的位置为最后最小索引值+1
1#
2# @lc app=leetcode.cn id=35 lang=python3
3#
4# [35] 搜索插入位置
5#
6
7# @lc code=start
8class Solution:
9 def searchInsert(self, nums: List[int], target: int) -> int:
10 m = 0
11 n = len(nums)-1
12 while m <= n:
13 k = (m + n) // 2
14 if target == nums[k]:
15 return k
16 elif target > nums[k]:
17 m = k + 1
18 else:
19 n = k - 1
20 return n+1
21# @lc code=end
62/62 cases passed (32 ms)
Your runtime beats 97.37 % of python3 submissions
Your memory usage beats 7.14 % of python3 submissions (14.3 MB)
实现 strStr() 函数。
给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = "hello", needle = "ll"
输出: 2
示例 2:
输入: haystack = "aaaaa", needle = "bba"
输出: -1
说明:
当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。
对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。
如果查找字符串为空或者两个字符串相同,直接返回0
定义两个变量i=needle长度, k=haystack长度
从0到k-i+1遍历haystack, 以i长度截取字符串对比needle, 如果找到返回当前索引
找不到返回-1
1#
2# @lc app=leetcode.cn id=28 lang=python3
3#
4# [28] 实现 strStr()
5#
6
7# @lc code=start
8class Solution:
9 def strStr(self, haystack: str, needle: str) -> int:
10 if not needle or haystack == needle:
11 return 0
12 j = len(needle)
13 k = len(haystack)
14 for i in range(k-j+1):
15 if haystack[i:i+j] == needle:
16 return i
17 return -1
18# @lc code=end
74/74 cases passed (36 ms)
Your runtime beats 91.04 % of python3 submissions
Your memory usage beats 6.67 % of python3 submissions (13.5 MB)
给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例 1:
给定 nums = [3,2,2,3], val = 3,
函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,1,2,2,3,0,4,2], val = 2,
函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。
注意这五个元素可为任意顺序。
你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝
int len = removeElement(nums, val);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中 该长度范围内 的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
定义两个变量i=0, j=0
i指向结果集, j从头到尾遍历数组
如果num[j]<>val, num[i]=num[j] 然后i=i+1, j=j+1
如果num[j]==val, 则j=j+1, 继续判断下一个元素
1#
2# @lc app=leetcode.cn id=27 lang=python3
3#
4# [27] 移除元素
5#
6
7# @lc code=start
8class Solution:
9 def removeElement(self, nums: List[int], val: int) -> int:
10 i = 0
11 j = 0
12 while True:
13 if j >= len(nums):
14 break
15 if nums[j] == val:
16 j = j + 1
17 else:
18 nums[i] = nums[j]
19 i = i + 1
20 j = j + 1
21 return i
22# @lc code=end
113/113 cases passed (36 ms)
Your runtime beats 87.21 % of python3 submissions
Your memory usage beats 7.14 % of python3 submissions (13.8 MB)
给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。
不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
示例 1:
给定数组 nums = [1,1,2],
函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。
你不需要考虑数组中超出新长度后面的元素。
示例 2:
给定 nums = [0,0,1,1,1,2,2,3,3,4],
函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。
你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
// nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝
int len = removeDuplicates(nums);
// 在函数里修改输入数组对于调用者是可见的。
// 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。
for (int i = 0; i < len; i++) {
print(nums[i]);
}
定义两个变量作为指针
i=0, j=1
i 作为结果指针, j 作为游标指向后面的元素, 用来跟结果比较
如果nums[i]==nums[j], 则j游标后移, 比较结果和下一个元素的值
如果nums[i]<>nums[j], 则nums[i+1] = nums[j], 然后i = i+1结果集后移一个, j游标后移
1#
2# @lc app=leetcode.cn id=26 lang=python3
3#
4# [26] 删除排序数组中的重复项
5#
6
7# @lc code=start
8class Solution:
9 def removeDuplicates(self, nums: List[int]) -> int:
10 i = 0
11 j = 1
12 while True:
13 if j >= len(nums):
14 break
15 if nums[j] != nums[i]:
16 nums[i+1] = nums[j]
17 i = i + 1
18 j = j + 1
19 return i + 1
20# @lc code=end
161/161 cases passed (40 ms)
Your runtime beats 95.72 % of python3 submissions
Your memory usage beats 8.16 % of python3 submissions (14.7 MB)
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例:
输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4
初始化一个新的链表want节点, 并用head变量保存头部
当l1和l2都不为空时, 比较两个链表的头部元素, 较小的赋值给新链接want, 并将链接指针后移
当l1或l2有一个为空时, 将不为空的链接剩余节点追加到want
最后返回head->next(即真正的链接第一个元素)
1#
2# @lc app=leetcode.cn id=21 lang=python3
3#
4# [21] 合并两个有序链表
5#
6
7# @lc code=start
8# Definition for singly-linked list.
9# class ListNode:
10# def __init__(self, val=0, next=None):
11# self.val = val
12# self.next = next
13class Solution:
14 def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
15 want = ListNode(0)
16 head = want
17 while l1 and l2:
18 if l1.val <= l2.val:
19 tmp = ListNode(l1.val)
20 l1 = l1.next
21 else:
22 tmp = ListNode(l2.val)
23 l2 = l2.next
24 want.next = tmp
25 want = want.next
26 if l1:
27 want.next = l1
28 if l2:
29 want.next = l2
30 return head.next
31# @lc code=end
208/208 cases passed (44 ms)
Your runtime beats 78.91 % of python3 submissions
Your memory usage beats 7.14 % of python3 submissions (13.8 MB)
给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串,判断字符串是否有效。
有效字符串需满足:
示例 1:
输入: "()"
输出: true
示例 2:
输入: "()[]{}"
输出: true
示例 3:
输入: "(]"
输出: false
示例 4:
输入: "([)]"
输出: false
示例 5:
输入: "{[]}"
输出: true
将给定字符串打散成数组
初始化字典, 右侧括号为键, 左侧括号为值
循环数组中的每个字符如果当前字符不是字典的键(即不是右侧括号), 将当前字符追加到一个空数组stack
否则(即当前字符是右侧括号),判断stack不为空的情况下, 最后一个元素是否等于字典中当前字符键的值
相等则继续判断下一个字符
不相等即返回False,
最后判断stack, 非空返回False
1#
2# @lc app=leetcode.cn id=20 lang=python3
3#
4# [20] 有效的括号
5#
6
7# @lc code=start
8class Solution:
9 def isValid(self, s: str) -> bool:
10 s = list(s)
11 dic = {")":"(","]":"[","}":"{"}
12 stack = []
13 for i in s:
14 if not i in dic:
15 stack.append(i)
16 else:
17 if stack and stack.pop() == dic[i]:
18 pass
19 else:
20 return False
21 return True if not stack else False
22# @lc code=end
76/76 cases passed (36 ms)
Your runtime beats 90.49 % of python3 submissions
Your memory usage beats 5.22 % of python3 submissions (13.8 MB)
编写一个函数来查找字符串数组中的最长公共前缀。
如果不存在公共前缀,返回空字符串 “"。
示例 1:
输入: ["flower","flow","flight"]
输出: "fl"
示例 2:
输入: ["dog","racecar","car"]
输出: ""
解释: 输入不存在公共前缀。
说明:
所有输入只包含小写字母 a-z 。
原始数组转为set,再转为list, 去重
如果只有一个元素, 最长公共前缀就是该元素
设置初始最长公共前缀为”"
对数组各元素同步截取前n个字符. 放入set去重, 如果set长度为1, 则公共前缀为集合的元素
继续对各元素同步截取, 直到set长度不为1, 返回保存的公共前缀
1#
2# @lc app=leetcode.cn id=14 lang=python3
3#
4# [14] 最长公共前缀
5#
6
7# @lc code=start
8class Solution:
9 def longestCommonPrefix(self, strs: List[str]) -> str:
10 strs = list(set(strs))
11 if len(strs) == 1:
12 return strs[0]
13 idx = 1
14 prefix = ""
15 while True:
16 ary = [i[0:idx] for i in strs]
17 if len(set(ary))==1:
18 prefix = ary[0]
19 idx = idx + 1
20 else:
21 break
22 return prefix
23
24# @lc code=end
118/118 cases passed (40 ms)
Your runtime beats 80.45 % of python3 submissions
Your memory usage beats 6.15 % of python3 submissions (13.7 MB)
罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。
字符 数值
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做 XXVII, 即为 XX + V + II 。
通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边, 所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:
I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。
给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。
示例 1:
输入: "III"
输出: 3
示例 2:
输入: "IV"
输出: 4
示例 3:
输入: "IX"
输出: 9
示例 4:
输入: "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.
示例 5:
输入: "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
初始化一个字典, 包含所有字符到数字的情况,
注意顺序先特殊情况处理, 防止后面单字符转换后特殊情况消失
将给定的字符串用字典的key-value替换, 再分割成数组, 剔除空值, 每个元素转为数字
用sum求和数组返回
1#
2# @lc app=leetcode.cn id=13 lang=python3
3#
4# [13] 罗马数字转整数
5#
6
7# @lc code=start
8class Solution:
9 def romanToInt(self, s: str) -> int:
10 dic = {
11 "IV": "+4+",
12 "IX": "+9+",
13 "XL": "+40+",
14 "XC": "+90+",
15 "CD": "+400+",
16 "CM": "+900+",
17 "I": "+1+",
18 "V": "+5+",
19 "X": "+10+",
20 "L": "+50+",
21 "C": "+100+",
22 "D": "+500+",
23 "M": "+1000+",
24 }
25 for k,v in dic.items():
26 s = s.replace(k,v)
27 return sum([int(i) for i in s.split("+") if i])
28
29# @lc code=end
3999/3999 cases passed (68 ms)
Your runtime beats 40.85 % of python3 submissions
Your memory usage beats 6.45 % of python3 submissions (13.7 MB)
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入: 121
输出: true
示例 2:
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。
进阶: 你能不将整数转为字符串来解决这个问题吗?
判断是否负数, 是负数直接返回False
正数的时候, 转化字符串再转为数组,
取数组长度的一半取整, 然后对数组前后各一半对比, 有一个不同则返回False, 否则返回True
1#
2# @lc app=leetcode.cn id=9 lang=python3
3#
4# [9] 回文数
5#
6
7# @lc code=start
8class Solution:
9 def isPalindrome(self, x: int) -> bool:
10 if x < 0:
11 return False
12 else:
13 ary = list(str(x))
14 lens = len(ary)
15 half = lens // 2
16 for i in range(0,half):
17 if ary[i] != ary[ -1 * (i + 1)]:
18 return False
19 return True
20
21# @lc code=end
11509/11509 cases passed (84 ms)
Your runtime beats 71.7 % of python3 submissions
Your memory usage beats 5.88 % of python3 submissions (13.8 MB)
首先判断负数, 直接返回False
正数的话, 原始x除10取余数赋值给y, x除10商赋值给s
如果s不为0, 则将商s赋值给x, 继续除10, 余数赋值给y = y*10 + 本次余数, 商继续赋值给s
知道商s为0, 此时判断 y==s 返回判断结果
1#
2# @lc app=leetcode.cn id=9 lang=python3
3#
4# [9] 回文数
5#
6
7# @lc code=start
8class Solution:
9 def isPalindrome(self, x: int) -> bool:
10 if x < 0:
11 return False
12 k = x
13 y = 0
14 while True:
15 y = x % 10 if y == 0 else y * 10 + x % 10
16 s = x // 10
17 if not s:
18 break
19 x = s
20 return y == k
21# @lc code=end
11509/11509 cases passed (88 ms)
Your runtime beats 60.61 % of python3 submissions
Your memory usage beats 5.88 % of python3 submissions (13.7 MB)
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。
示例 1:
输入: 123
输出: 321
示例 2:
输入: -123
输出: -321
示例 3:
输入: 120
输出: 21
注意:
假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。
判断是否负数, 转为正整数
将正整数转为字符串, 再转换为列表, 使用reverse函数翻转, 最后用join组合起来
还原给出的正负符号
最后输出前判断是否超出32 位的有符号整数
1#
2# @lc app=leetcode.cn id=7 lang=python3
3#
4# [7] 整数反转
5#
6
7# @lc code=start
8class Solution:
9 def reverse(self, x: int) -> int:
10 if x < 0:
11 x = list(str(-1 * x))
12 x.reverse()
13 y = -1 * int(''.join(x))
14 else:
15 x = list(str(x))
16 x.reverse()
17 y = int(''.join(x))
18 if y < -1 * 2 ** 31 or y > 2 ** 31 -1:
19 return 0
20 else:
21 return y
22# @lc code=end
1032/1032 cases passed (48 ms)
Your runtime beats 44.33 % of python3 submissions
Your memory usage beats 6.67 % of python3 submissions (13.8 MB)
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]
从列表头部开始每次取出一个数字: A, 并记录取数的索引: k,
在剩余的数组: ary[k+1:] 中查找: target - A 的索引 j,
如果找到返回: [k,j], 没有找到就从头部继续往后取出数字.
1#
2# @lc app=leetcode.cn id=1 lang=python3
3#
4# [1] 两数之和
5#
6
7# @lc code=start
8class Solution:
9 def twoSum(self, nums: List[int], target: int) -> List[int]:
10 cnt = 0
11 while len(nums):
12 a = nums.pop(0)
13 want = target - a
14 if want in nums:
15 idx = nums.index(want)
16 return [cnt, idx+cnt+1]
17 cnt = cnt + 1
18
19# @lc code=end
1#
2# @lc app=leetcode.cn id=1 lang=python3
3#
4# [1] 两数之和
5#
6
7# @lc code=start
8class Solution:
9 def twoSum(self, nums: List[int], target: int) -> List[int]:
10 cnt = 0
11 lens = len(nums)
12 while cnt < lens - 1:
13 a = nums[cnt]
14 if target - a in nums[cnt + 1:]:
15 return [cnt,nums.index(target - a, cnt + 1)]
16 cnt = cnt + 1
17
18# @lc code=end
29/29 cases passed (768 ms)
Your runtime beats 43.42 % of python3 submissions
Your memory usage beats 13.41 % of python3 submissions (14.6 MB)
在Linux下升级最新版openssl
在官网https://www.openssl.org/source/ 页面可以下载最新源码包
当前最新版地址: https://www.openssl.org/source/openssl-3.1.2.tar.gz
使用命令 wget https://www.openssl.org/source/openssl-3.1.2.tar.gz
1
2tar -zxvf openssl-3.1.2.tar.gz
3cd openssl-3.1.2
4./config --prefix=/usr/local/openssl
5make && make install
1
2echo "/usr/local/openssl/lib64/" >> /etc/ld.so.conf
3ldconfig
4
5mv /usr/bin/openssl /usr/bin/openssl.old
6ln -sv /usr/local/openssl/bin/openssl /usr/bin/openssl
7
8openssl version
升级openssl完成后, 编译安装Python
./configure -C --with-openssl=/usr/local/openssl --with-openssl-rpath=auto --prefix=/usr/local/Python3.11
Raspberry Pi 基金会开发的一款微型电脑
树莓派,(英语:Raspberry Pi,简写为RPi,别名为RasPi/RPI)是为学习计算机编程教育而设计,只有信用卡大小的微型电脑,其系统基于Linux。
随着Windows 10 IoT的发布,用户可以用上运行Windows的树莓派。
Raspberry Pi 初次安装运行后, 一些必要的配置, 可以更好的运行使用.
ssh 用来启用ssh登录.wpa_supplicant.conf1ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
2update_config=1
3country=CN
4
5network={
6 ssid="yourssid"
7 psk="yourwifipwd"
8 key_mgmt=WPA-PSK
9}
1# 登录raspberry后修改pi用户密码
2passwd
3# 修改root用户密码
4sudo passwd root
5# 解锁root用户
6sudo passwd --unlock root
sudo dpkg-reconfigure tzdata
1#更改apt软件源
2sudo sed -i 's|raspbian.raspberrypi.org|mirrors.ustc.edu.cn/raspbian|g' /etc/apt/sources.list
3#更改raspberrypi软件源
4sudo sed -i 's|//archive.raspberrypi.org|//mirrors.ustc.edu.cn/archive.raspberrypi.org|g' /etc/apt/sources.list.d/raspi.list
5#更新源
6sudo apt-get update
sudo raspi-config
选择Advancd Options -> Expand Filesystem 然后重启
Centos 升级指定版本Python
最近升级Python3.10, 发现centos自带ssl包版本过低, 所以在升级脚本中添加了ssl的升级过程
执行脚本完成后, 自动建立
python3pip3软连接
1
2#!/bin/bash
3
4
5function log(){
6 echo -e "\033[31m" ">>>>>> " $(date +"%Y-%m-%d %H:%M:%S") $@ " <<<<<<" "\033[0m"
7 sleep 2
8}
9
10
11parent_dir=$(pwd)/
12
13
14# 基础变量
15install_python_version=3.10.0
16install_openssl_version=1.1.1l
17
18
19shortver=${install_python_version%.*}
20doubleshort=${shortver/./}
21python_packagename=Python-${install_python_version}
22local_python_dir=/usr/local/${python_packagename}/
23pyM=/usr/bin/python${install_python_version%%.*}
24piM=/usr/bin/pip${install_python_version%%.*}
25pyN=/usr/bin/python${doubleshort}
26piN=/usr/bin/pip${doubleshort}
27
28
29# https://www.openssl.org/source/openssl-3.0.0.tar.gz
30# https://www.openssl.org/source/openssl-1.1.1l.tar.gz
31openssl_packagename=openssl-${install_openssl_version}
32
33
34# centos环境升级
35# log "yum libary"
36# yum update
37# yum install -y gcc libffi-devel zlib* openssl-devel libffi-devel \
38# zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make
39
40
41# debian环境升级
42#apt-get install zlib1g-dev libbz2-dev libssl-dev libncurses5-dev libsqlite3-dev libreadline-dev
43# tk-dev libgdbm-dev libdb-dev libpcap-dev xz-utils libexpat1-dev liblzma-dev libffi-dev libc6-dev
44
45
46# 建立软件包目录
47log "mkdir sofrware dir and into"
48soft_dir=${parent_dir}soft/
49[[ ! -d "${soft_dir}" ]] && mkdir -p "${soft_dir}"
50pushd ${soft_dir}
51
52
53# 移除备份旧文件
54log "remove old files"
55rm -fr ${python_packagename}
56rm -fr ${local_python_dir}
57[[ -f ${pyM} ]] && mv -f ${pyM}{,.bak}
58[[ -f ${piM} ]] && mv -f ${piM}{,.bak}
59[[ -f ${pyN} ]] && mv -f ${pyN}{,.bak}
60[[ -f ${piN} ]] && mv -f ${piN}{,.bak}
61
62
63# 下载新版源码
64log "curl openssl and python source, then untar"
65pyurl=https://www.python.org/ftp/python/${install_python_version}/${python_packagename}.tgz
66log ${pyurl}
67if [[ ! -f "${soft_dir}${python_packagename}.tgz" ]]; then
68 curl -O ${pyurl}
69fi
70if [[ ! -f "${soft_dir}${python_packagename}.tgz" ]]; then
71 log ${python_packagename}.tgz Download Failed
72fi
73tar -zxvf ${soft_dir}${python_packagename}.tgz
74
75
76opurl=https://www.openssl.org/source/${openssl_packagename}.tar.gz
77log opurl
78if [[ ! -f "${soft_dir}${openssl_packagename}.tar.gz" ]]; then
79 curl -O ${opurl}
80 exit 1
81fi
82if [[ ! -f "${soft_dir}${openssl_packagename}.tar.gz" ]]; then
83 log ${openssl_packagename}.tar.gz Download Failed
84 exit 1
85fi
86tar -zxvf ${soft_dir}${openssl_packagename}.tar.gz
87
88
89# 安装新openssl
90log "install new openssl"
91sslcnf=$(find /etc/ -name openssl.cnf -printf "%h\n")
92pushd ${openssl_packagename}
93./config --prefix=/usr/local/custom-openssl --libdir=lib --openssldir=${sslcnf}
94make -j1 depend
95make -j8
96make install_sw
97popd
98
99
100# 解压源码, 编译安装
101log "into source dir and compile python"
102pushd ${python_packagename}
103./configure -C --with-openssl=/usr/local/custom-openssl --with-openssl-rpath=auto --prefix=${local_python_dir}
104make -j8
105make altinstall
106popd
107
108
109# 建立链接文件
110log "link executable files"
111ln -s ${local_python_dir}bin/python${shortver} ${pyM}
112ln -s ${local_python_dir}bin/python${shortver} ${pyN}
113ln -s ${local_python_dir}bin/pip${shortver} ${piM}
114ln -s ${local_python_dir}bin/pip${shortver} ${piN}
115
116
117# 升级环境包
118log "upgrade pip"
119${piN} install -i https://pypi.tuna.tsinghua.edu.cn/simple --upgrade pip
120
121
122# 设置腾讯源
123${piN} config set global.index-url https://mirrors.cloud.tencent.com/pypi/simple
1# 下载最新版
2wget https://www.sqlite.org/2021/sqlite-autoconf-3370000.tar.gz --no-check-certificate
3tar -zxvf sqlite-autoconf-3370000.tar.gz
4cd sqlite-autoconf-3370000/
5./configure --prefix=/usr/local/ && make && make install
1export LD_LIBRARY_PATH="/usr/local/lib/"
curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。
-v, –verbose 输出信息 -q, –disable 在第一个参数位置设置后 .curlrc 的设置直接失效,这个参数会影响到 -K, –config -A, –user-agent -e, –referer -K, –config FILE 指定配置文件 -L, –location 跟踪重定向 (H)
-s, –silent Silent模式。不输出任务内容 -S, –show-error 显示错误. 在选项 -s 中,当 curl 出现错误时将显示 -f, –fail 不显示 连接失败时HTTP错误信息 -i, –include 显示 response的header (H/F) -I, –head 仅显示 响应文档头 -l, –list-only 只列出FTP目录的名称 (F) -#, –progress-bar 以进度条 显示传输进度
-X, –request [GET|POST|PUT|DELETE|…] 使用指定的 http method 例如 -X POST
-H, –header
-C, –continue-at OFFSET 断点续转 -x, –proxy [PROTOCOL://]HOST[:PORT] 在指定的端口上使用代理 -U, –proxy-user USER[:PASSWORD] 代理用户名及密码
-T, –upload-file
-o, –output
-A参数指定客户端的用户代理标头,即User-Agent。curl 的默认用户代理字符串是curl/[version]。
curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' https://google.com
通过-H参数直接指定标头,更改User-Agent。
curl -H 'User-Agent: php/1.0' https://google.com
-b参数用来向服务器发送 Cookie。
curl -b 'foo=bar' https://google.com
curl -b 'foo1=bar;foo2=bar2' https://google.com
curl -b cookies.txt https://www.google.com
-c参数将服务器设置的 Cookie 写入一个文件。
curl -c cookies.txt https://www.google.com
-d参数用于发送 POST 请求的数据体。
curl -d'login=emma&password=123'-X POST https://google.com/login
curl -d 'login=emma' -d 'password=123' -X POST https://google.com/login
使用-d参数以后,HTTP 请求会自动加上标头 Content-Type : application/x-www-form-urlencoded 。
并且会自动将请求转为 POST 方法,因此可以省略-X POST。
–data-urlencode 参数等同于-d,发送 POST 请求的数据体,区别在于会自动将发送的数据进行 URL 编码。
curl --data-urlencode 'comment=hello world' https://google.com/login
-e参数用来设置 HTTP 的标头Referer,表示请求的来源。
curl -e 'https://google.com?q=example' https://www.example.com
-H参数可以通过直接添加标头Referer,达到同样效果。
curl -H 'Referer: https://google.com?q=example' https://www.example.com
-F参数用来向服务器上传二进制文件。
curl -F 'file=@photo.png' https://google.com/profile
命令会给 HTTP 请求加上标头Content-Type: multipart/form-data,然后将文件photo.png作为file字段上传。
-F参数可以指定 MIME 类型。
curl -F 'file=@photo.png;type=image/png' https://google.com/profile
上面命令指定 MIME 类型为image/png,否则 curl 会把 MIME 类型设为application/octet-stream。
curl -F 'file=@photo.png;filename=me.png' https://google.com/profile
上面命令中,原始文件名为photo.png,但是服务器接收到的文件名为me.png。
-G参数用来构造 URL 的查询字符串
curl -G -d 'q=kitties' -d 'count=20' https://google.com/search
上面命令会发出一个 GET 请求,实际请求的URL为https://google.com/search?q=kitties&count=20。如果省略–G,会发出一个 POST 请求。
curl -G --data-urlencode 'comment=hello world' https://www.example.com
如果数据需要 URL 编码,可以结合--data--urlencode参数。
-H参数添加 HTTP 请求的标头。
curl -H 'Accept-Language: en-US' https://google.com
curl -H 'Accept-Language: en-US' -H 'Secret-Message: xyzzy' https://google.com
curl -d '{"login": "emma", "pass": "123"}' -H 'Content-Type: application/json' https://google.com/login
-i参数打印出服务器回应的 HTTP 标头。
curl -i https://www.example.com
上面命令收到服务器回应后,先输出服务器回应的标头,然后空一行,再输出网页的源码。
-I参数向服务器发出 HEAD 请求,然会将服务器返回的 HTTP 标头打印出来。
curl -I https://www.example.com
上面命令输出服务器对 HEAD 请求的回应。
–head参数等同于-I。
curl --head https://www.example.com
-k参数指定跳过 SSL 检测。
curl -k https://www.example.com
–limit-rate用来限制 HTTP 请求和回应的带宽,模拟慢网速的环境。
curl --limit-rate 200k https://google.com
-o参数将服务器的回应保存成文件,等同于wget命令。
curl -o example.html https://www.example.com
-O参数将服务器回应保存成文件,并将 URL 的最后部分当作文件名。
curl -O https://www.example.com/foo/bar.html
-s参数将不输出错误和进度信息。
curl -s https://www.example.com
-u参数用来设置服务器认证的用户名和密码。
curl -u 'bob:12345' https://google.com/login
上面命令设置用户名为bob,密码为12345,
然后将其转为 HTTP 标头Authorization: Basic Ym9iOjEyMzQ1。
curl https://bob:12345@google.com/login
上面命令能够识别 URL 里面的用户名和密码,将其转为上个例子里面的 HTTP 标头。
curl -u 'bob' https://google.com/login
上面命令只设置了用户名,执行后,curl 会提示用户输入密码。
-x参数指定 HTTP 请求的代理。
curl -x socks5://james:cats@myproxy.com:8080 https://www.example.com
上面命令指定 HTTP 请求通过myproxy.com:8080的 socks5 代理发出。
curl -x james:cats@myproxy.com:8080 https://www.example.com
如果没有指定代理协议,默认为 HTTP
-X参数指定 HTTP 请求的方法。
curl -X POST https://www.example.com
-r 0-100 分段下载
curl -r 0-100 -o img.part1 http://mydomian.cn/thumb/xxx.jpg
curl -r 100-200 -o img.part2 http://mydomian.cn/thumb/xxx.jpg
最后合并cat所有文件
curl http://mydomain.net > index.html
curl -o index.html http://mydomain.net
curl -O http://mydomain.net/target.tar.gz
GET
curl http://www.yahoo.com/login.cgi?user=nickname&password=12345
POST
curl -d "user=nickname&password=12345" http://www.yahoo.com/login.cgi
POST文件
curl -F upload= $localfile -F $btn_name=$btn_value http://mydomain.net/~zzh/up_file.cgi
通过代理
curl -x 123.45.67.89:1080 -o page.html http://mydomain.net
保存Cookie
curl -x 123.45.67.89:1080 -o page1.html -D cookie0001.txt http://mydomain.net
使用Cookie
curl -x 123.45.67.89:1080 -o page1.html -D cookie0002.txt -b cookie0001.txt http://mydomain.net
模仿浏览器
curl -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -x123.45.67.89:1080 -o page.html -D cookie0001.txt http://mydomain.net
伪造referer
curl -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -x123.45.67.89:1080 -e"mail.yahoo.com" -o page.html -D cookie0001.txt http://mydomain.net
循环下载
curl -O http://mydomain.net/~zzh/screen[1-10].JPG
循环匹配下载
curl -O http://mydomain.net/~{zzh,nick}/[001-201].JPG # >like zzh/001.JPG
循环引用下载
curl -o #2_#1.jpg http://mydomain.net/~{zzh,nick}/[001-201].JPG # like >001_zzh.jpg
断点续传
curl -c -O http://mydomain.net/~zzh/screen1.JPG
分块下载
curl -r 0 -10240 -o "zhao.part1" http://mydomain.net/~zzh/zhao1.mp3 &\
curl -r 10241 -20480 -o "zhao.part1" http://mydomain.net/~zzh/zhao1.mp3 &\
curl -r 20481 -40960 -o "zhao.part1" http://mydomain.net/~zzh/zhao1.mp3 &\
curl -r 40961 - -o "zhao.part1" http://mydomain.net/~zzh/zhao1.mp3
..
cat zhao.part* > zhao.mp3
在以下选项中,(H) 表示仅适用 HTTP/HTTPS ,(F) 表示仅适用于 FTP
--anyauth 选择 "any" 认证方法 (H)
-a, --append 添加要上传的文件 (F/SFTP)
--basic 使用HTTP基础认证(Basic Authentication)(H)
--cacert FILE CA 证书,用于每次请求认证 (SSL)
--capath DIR CA 证书目录 (SSL)
-E, --cert CERT[:PASSWD] 客户端证书文件及密码 (SSL)
--cert-type TYPE 证书文件类型 (DER/PEM/ENG) (SSL)
--ciphers LIST SSL 秘钥 (SSL)
--compressed 请求压缩 (使用 deflate 或 gzip)
-K, --config FILE 指定配置文件
--connect-timeout SECONDS 连接超时设置
-C, --continue-at OFFSET 断点续转
-b, --cookie STRING/FILE Cookies字符串或读取Cookies的文件位置 (H)
-c, --cookie-jar FILE 操作结束后,要写入 Cookies 的文件位置 (H)
--create-dirs 创建必要的本地目录层次结构
--crlf 在上传时将 LF 转写为 CRLF
--crlfile FILE 从指定的文件获得PEM格式CRL列表
-d, --data DATA HTTP POST 数据 (H)
--data-ascii DATA ASCII 编码 HTTP POST 数据 (H)
--data-binary DATA binary 编码 HTTP POST 数据 (H)
--data-urlencode DATA url 编码 HTTP POST 数据 (H)
--delegation STRING GSS-API 委托权限
--digest 使用数字身份验证 (H)
--disable-eprt 禁止使用 EPRT 或 LPRT (F)
--disable-epsv 禁止使用 EPSV (F)
-D, --dump-header FILE 将头信息写入指定的文件
--egd-file FILE 为随机数据设置EGD socket路径(SSL)
--engine ENGINGE 加密引擎 (SSL). "--engine list" 指定列表
-f, --fail 连接失败时不显示HTTP错误信息 (H)
-F, --form CONTENT 模拟 HTTP 表单数据提交(multipart POST) (H)
--form-string STRING 模拟 HTTP 表单数据提交 (H)
--ftp-account DATA 帐户数据提交 (F)
--ftp-alternative-to-user COMMAND 指定替换 "USER [name]" 的字符串 (F)
--ftp-create-dirs 如果不存在则创建远程目录 (F)
--ftp-method [MULTICWD/NOCWD/SINGLECWD] 控制 CWD (F)
--ftp-pasv 使用 PASV/EPSV 替换 PORT (F)
-P, --ftp-port ADR 使用指定 PORT 及地址替换 PASV (F)
--ftp-skip-pasv-ip 跳过 PASV 的IP地址 (F)
--ftp-pret 在 PASV 之前发送 PRET (drftpd) (F)
--ftp-ssl-ccc 在认证之后发送 CCC (F)
--ftp-ssl-ccc-mode ACTIVE/PASSIVE 设置 CCC 模式 (F)
--ftp-ssl-control ftp 登录时需要 SSL/TLS (F)
-G, --get 使用 HTTP GET 方法发送 -d 数据 (H)
-g, --globoff 禁用的 URL 队列 及范围使用 {} 和 []
-H, --header LINE 要发送到服务端的自定义请求头 (H)
-I, --head 仅显示响应文档头
-h, --help 显示帮助
-0, --http1.0 使用 HTTP 1.0 (H)
--ignore-content-length 忽略 HTTP Content-Length 头
-i, --include 在输出中包含协议头 (H/F)
-k, --insecure 允许连接到 SSL 站点,而不使用证书 (H)
--interface INTERFACE 指定网络接口/地址
-4, --ipv4 将域名解析为 IPv4 地址
-6, --ipv6 将域名解析为 IPv6 地址
-j, --junk-session-cookies 读取文件中但忽略会话cookie (H)
--keepalive-time SECONDS keepalive 包间隔
--key KEY 私钥文件名 (SSL/SSH)
--key-type TYPE 私钥文件类型 (DER/PEM/ENG) (SSL)
--krb LEVEL 启用指定安全级别的 Kerberos (F)
--libcurl FILE 命令的libcurl等价代码
--limit-rate RATE 限制传输速度
-l, --list-only 只列出FTP目录的名称 (F)
--local-port RANGE 强制使用的本地端口号
-L, --location 跟踪重定向 (H)
--location-trusted 类似 --location 并发送验证信息到其它主机 (H)
-M, --manual 显示全手动
--mail-from FROM 从这个地址发送邮件
--mail-rcpt TO 发送邮件到这个接收人(s)
--mail-auth AUTH 原始电子邮件的起始地址
--max-filesize BYTES 下载的最大文件大小 (H/F)
--max-redirs NUM 最大重定向数 (H)
-m, --max-time SECONDS 允许的最多传输时间
--metalink 处理指定的URL上的XML文件
--negotiate 使用 HTTP Negotiate 认证 (H)
-n, --netrc 必须从 .netrc 文件读取用户名和密码
--netrc-optional 使用 .netrc 或 URL; 将重写 -n 参数
--netrc-file FILE 设置要使用的 netrc 文件名
-N, --no-buffer 禁用输出流的缓存
--no-keepalive 禁用 connection 的 keepalive
--no-sessionid 禁止重复使用 SSL session-ID (SSL)
--noproxy 不使用代理的主机列表
--ntlm 使用 HTTP NTLM 认证 (H)
-o, --output FILE 将输出写入文件,而非 stdout
--pass PASS 传递给私钥的短语 (SSL/SSH)
--post301 在 301 重定向后不要切换为 GET 请求 (H)
--post302 在 302 重定向后不要切换为 GET 请求 (H)
--post303 在 303 重定向后不要切换为 GET 请求 (H)
-#, --progress-bar 以进度条显示传输进度
--proto PROTOCOLS 启用/禁用 指定的协议
--proto-redir PROTOCOLS 在重定向上 启用/禁用 指定的协议
-x, --proxy [PROTOCOL://]HOST[:PORT] 在指定的端口上使用代理
--proxy-anyauth 在代理上使用 "any" 认证方法 (H)
--proxy-basic 在代理上使用 Basic 认证 (H)
--proxy-digest 在代理上使用 Digest 认证 (H)
--proxy-negotiate 在代理上使用 Negotiate 认证 (H)
--proxy-ntlm 在代理上使用 NTLM 认证 (H)
-U, --proxy-user USER[:PASSWORD] 代理用户名及密码
--proxy1.0 HOST[:PORT] 在指定的端口上使用 HTTP/1.0 代理
-p, --proxytunnel 使用HTTP代理 (用于 CONNECT)
--pubkey KEY 公钥文件名 (SSH)
-Q, --quote CMD 在传输开始前向服务器发送命令 (F/SFTP)
--random-file FILE 读取随机数据的文件 (SSL)
-r, --range RANGE 仅检索范围内的字节
--raw 使用原始HTTP传输,而不使用编码 (H)
-e, --referer Referer URL (H)
-J, --remote-header-name 从远程文件读取头信息 (H)
-O, --remote-name 将输出写入远程文件
--remote-name-all 使用所有URL的远程文件名
-R, --remote-time 将远程文件的时间设置在本地输出上
-X, --request COMMAND 使用指定的请求命令
--resolve HOST:PORT:ADDRESS 将 HOST:PORT 强制解析到 ADDRESS
--retry NUM 出现问题时的重试次数
--retry-delay SECONDS 重试时的延时时长
--retry-max-time SECONDS 仅在指定时间段内重试
-S, --show-error 显示错误. 在选项 -s 中,当 curl 出现错误时将显示
-s, --silent Silent模式。不输出任务内容
--socks4 HOST[:PORT] 在指定的 host + port 上使用 SOCKS4 代理
--socks4a HOST[:PORT] 在指定的 host + port 上使用 SOCKSa 代理
--socks5 HOST[:PORT] 在指定的 host + port 上使用 SOCKS5 代理
--socks5-hostname HOST[:PORT] SOCKS5 代理,指定用户名、密码
--socks5-gssapi-service NAME 为gssapi使用SOCKS5代理服务名称
--socks5-gssapi-nec 与NEC Socks5服务器兼容
-Y, --speed-limit RATE 在指定限速时间之后停止传输
-y, --speed-time SECONDS 指定时间之后触发限速. 默认 30
--ssl 尝试 SSL/TLS (FTP, IMAP, POP3, SMTP)
--ssl-reqd 需要 SSL/TLS (FTP, IMAP, POP3, SMTP)
-2, --sslv2 使用 SSLv2 (SSL)
-3, --sslv3 使用 SSLv3 (SSL)
--ssl-allow-beast 允许的安全漏洞,提高互操作性(SSL)
--stderr FILE 重定向 stderr 的文件位置. - means stdout
--tcp-nodelay 使用 TCP_NODELAY 选项
-t, --telnet-option OPT=VAL 设置 telnet 选项
--tftp-blksize VALUE 设备 TFTP BLKSIZE 选项 (必须 >512)
-z, --time-cond TIME 基于时间条件的传输
-1, --tlsv1 使用 => TLSv1 (SSL)
--tlsv1.0 使用 TLSv1.0 (SSL)
--tlsv1.1 使用 TLSv1.1 (SSL)
--tlsv1.2 使用 TLSv1.2 (SSL)
--trace FILE 将 debug 信息写入指定的文件
--trace-ascii FILE 类似 --trace 但使用16进度输出
--trace-time 向 trace/verbose 输出添加时间戳
--tr-encoding 请求压缩传输编码 (H)
-T, --upload-file FILE 将文件传输(上传)到指定位置
--url URL 指定所使用的 URL
-B, --use-ascii 使用 ASCII/text 传输
-u, --user USER[:PASSWORD] 指定服务器认证用户名、密码
--tlsuser USER TLS 用户名
--tlspassword STRING TLS 密码
--tlsauthtype STRING TLS 认证类型 (默认 SRP)
--unix-socket FILE 通过这个 UNIX socket 域连接
-A, --user-agent STRING 要发送到服务器的 User-Agent (H)
-v, --verbose 显示详细操作信息
-V, --version 显示版本号并退出
-w, --write-out FORMAT 完成后输出什么
--xattr 将元数据存储在扩展文件属性中
-q .curlrc 如果作为第一个参数无效
curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。
-v, --verbose 输出信息
-q, --disable 在第一个参数位置设置后 .curlrc 的设置直接失效,
这个参数会影响到 -K, --config -A, --user-agent -e, --referer
-K, --config FILE 指定配置文件
-L, --location 跟踪重定向 (H)
-s, --silent Silent模式。不输出任务内容
-S, --show-error 显示错误. 在选项 -s 中,当 curl 出现错误时将显示
-f, --fail 不显示 连接失败时HTTP错误信息
-i, --include 显示 response的header (H/F)
-I, --head 仅显示 响应文档头
-l, --list-only 只列出FTP目录的名称 (F)
-#, --progress-bar 以进度条 显示传输进度
-X, --request [GET|POST|PUT|DELETE|…] 使用指定的 http method 例如 -X POST
-H, --header <header> 设定 request里的header 例如 -H "Content-Type: application/json"
-e, --referer 设定 referer (H)
-d, --data <data> 设定 http body 默认使用 content-type application/x-www-form-urlencoded (H)
--data-raw <data> ASCII 编码 HTTP POST 数据 (H)
--data-binary <data> binary 编码 HTTP POST 数据 (H)
--data-urlencode <data> url 编码 HTTP POST 数据 (H)
-G, --get 使用 HTTP GET 方法发送 -d 数据 (H)
-F, --form <name=string> 模拟 HTTP 表单数据提交 multipart POST (H)
--form-string <name=string> 模拟 HTTP 表单数据提交 (H)
-u, --user <user:password> 使用帐户,密码 例如 admin:password
-b, --cookie <data> cookie 文件 (H)
-j, --junk-session-cookies 读取文件中但忽略会话cookie (H)
-A, --user-agent user-agent设置 (H)
-C, --continue-at OFFSET 断点续转
-x, --proxy [PROTOCOL://]HOST[:PORT] 在指定的端口上使用代理
-U, --proxy-user USER[:PASSWORD] 代理用户名及密码
-T, --upload-file <file> 上传文件
-a, --append 添加要上传的文件 (F/SFTP)
-o, --output <file> 将输出写入文件,而非 stdout
-O, --remote-name 将输出写入远程文件
-D, --dump-header <file> 将头信息写入指定的文件
-c, --cookie-jar <file> 操作结束后,要写入 Cookies 的文件位置
-A参数指定客户端的用户代理标头,即User-Agent。curl 的默认用户代理字符串是curl/[version]。
curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' https://google.com
通过-H参数直接指定标头,更改User-Agent。
curl -H 'User-Agent: php/1.0' https://google.com
-b参数用来向服务器发送 Cookie。
curl -b 'foo=bar' https://google.com
curl -b 'foo1=bar;foo2=bar2' https://google.com
curl -b cookies.txt https://www.google.com
-c参数将服务器设置的 Cookie 写入一个文件。
curl -c cookies.txt https://www.google.com
-d参数用于发送 POST 请求的数据体。
curl -d'login=emma&password=123'-X POST https://google.com/login
curl -d 'login=emma' -d 'password=123' -X POST https://google.com/login
使用-d参数以后,HTTP 请求会自动加上标头 Content-Type : application/x-www-form-urlencoded 。
并且会自动将请求转为 POST 方法,因此可以省略-X POST。
–data-urlencode 参数等同于-d,发送 POST 请求的数据体,区别在于会自动将发送的数据进行 URL 编码。
curl --data-urlencode 'comment=hello world' https://google.com/login
-e参数用来设置 HTTP 的标头Referer,表示请求的来源。
curl -e 'https://google.com?q=example' https://www.example.com
-H参数可以通过直接添加标头Referer,达到同样效果。
curl -H 'Referer: https://google.com?q=example' https://www.example.com
-F参数用来向服务器上传二进制文件。
curl -F 'file=@photo.png' https://google.com/profile
命令会给 HTTP 请求加上标头Content-Type: multipart/form-data,然后将文件photo.png作为file字段上传。
-F参数可以指定 MIME 类型。
curl -F 'file=@photo.png;type=image/png' https://google.com/profile
上面命令指定 MIME 类型为image/png,否则 curl 会把 MIME 类型设为application/octet-stream。
curl -F 'file=@photo.png;filename=me.png' https://google.com/profile
上面命令中,原始文件名为photo.png,但是服务器接收到的文件名为me.png。
-G参数用来构造 URL 的查询字符串
curl -G -d 'q=kitties' -d 'count=20' https://google.com/search
上面命令会发出一个 GET 请求,实际请求的URL为https://google.com/search?q=kitties&count=20。如果省略–G,会发出一个 POST 请求。
curl -G --data-urlencode 'comment=hello world' https://www.example.com
如果数据需要 URL 编码,可以结合--data--urlencode参数。
-H参数添加 HTTP 请求的标头。
curl -H 'Accept-Language: en-US' https://google.com
curl -H 'Accept-Language: en-US' -H 'Secret-Message: xyzzy' https://google.com
curl -d '{"login": "emma", "pass": "123"}' -H 'Content-Type: application/json' https://google.com/login
-i参数打印出服务器回应的 HTTP 标头。
curl -i https://www.example.com
上面命令收到服务器回应后,先输出服务器回应的标头,然后空一行,再输出网页的源码。
-I参数向服务器发出 HEAD 请求,然会将服务器返回的 HTTP 标头打印出来。
curl -I https://www.example.com
上面命令输出服务器对 HEAD 请求的回应。
–head参数等同于-I。
curl --head https://www.example.com
-k参数指定跳过 SSL 检测。
curl -k https://www.example.com
–limit-rate用来限制 HTTP 请求和回应的带宽,模拟慢网速的环境。
curl --limit-rate 200k https://google.com
-o参数将服务器的回应保存成文件,等同于wget命令。
curl -o example.html https://www.example.com
-O参数将服务器回应保存成文件,并将 URL 的最后部分当作文件名。
curl -O https://www.example.com/foo/bar.html
-s参数将不输出错误和进度信息。
curl -s https://www.example.com
-u参数用来设置服务器认证的用户名和密码。
curl -u 'bob:12345' https://google.com/login
上面命令设置用户名为bob,密码为12345,
然后将其转为 HTTP 标头Authorization: Basic Ym9iOjEyMzQ1。
curl https://bob:12345@google.com/login
上面命令能够识别 URL 里面的用户名和密码,将其转为上个例子里面的 HTTP 标头。
curl -u 'bob' https://google.com/login
上面命令只设置了用户名,执行后,curl 会提示用户输入密码。
-x参数指定 HTTP 请求的代理。
curl -x socks5://james:cats@myproxy.com:8080 https://www.example.com
上面命令指定 HTTP 请求通过myproxy.com:8080的 socks5 代理发出。
curl -x james:cats@myproxy.com:8080 https://www.example.com
如果没有指定代理协议,默认为 HTTP
-X参数指定 HTTP 请求的方法。
curl -X POST https://www.example.com
-r 0-100 分段下载
curl -r 0-100 -o img.part1 http://mydomian.cn/thumb/xxx.jpg
curl -r 100-200 -o img.part2 http://mydomian.cn/thumb/xxx.jpg
最后合并cat所有文件
curl http://mydomain.net > index.html
curl -o index.html http://mydomain.net
curl -O http://mydomain.net/target.tar.gz
GET
curl http://www.yahoo.com/login.cgi?user=nickname&password=12345
POST
curl -d "user=nickname&password=12345" http://www.yahoo.com/login.cgi
POST文件
curl -F upload= $localfile -F $btn_name=$btn_value http://mydomain.net/~zzh/up_file.cgi
通过代理
curl -x 123.45.67.89:1080 -o page.html http://mydomain.net
保存Cookie
curl -x 123.45.67.89:1080 -o page1.html -D cookie0001.txt http://mydomain.net
使用Cookie
curl -x 123.45.67.89:1080 -o page1.html -D cookie0002.txt -b cookie0001.txt http://mydomain.net
模仿浏览器
curl -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -x123.45.67.89:1080 -o page.html -D cookie0001.txt http://mydomain.net
伪造referer
curl -A "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" -x123.45.67.89:1080 -e"mail.yahoo.com" -o page.html -D cookie0001.txt http://mydomain.net
循环下载
curl -O http://mydomain.net/~zzh/screen[1-10].JPG
循环匹配下载
curl -O http://mydomain.net/~{zzh,nick}/[001-201].JPG # >like zzh/001.JPG
循环引用下载
curl -o #2_#1.jpg http://mydomain.net/~{zzh,nick}/[001-201].JPG # like >001_zzh.jpg
断点续传
curl -c -O http://mydomain.net/~zzh/screen1.JPG
分块下载
curl -r 0 -10240 -o "zhao.part1" http://mydomain.net/~zzh/zhao1.mp3 &\
curl -r 10241 -20480 -o "zhao.part1" http://mydomain.net/~zzh/zhao1.mp3 &\
curl -r 20481 -40960 -o "zhao.part1" http://mydomain.net/~zzh/zhao1.mp3 &\
curl -r 40961 - -o "zhao.part1" http://mydomain.net/~zzh/zhao1.mp3
..
cat zhao.part* > zhao.mp3
在以下选项中,(H) 表示仅适用 HTTP/HTTPS ,(F) 表示仅适用于 FTP
--anyauth 选择 "any" 认证方法 (H)
-a, --append 添加要上传的文件 (F/SFTP)
--basic 使用HTTP基础认证(Basic Authentication)(H)
--cacert FILE CA 证书,用于每次请求认证 (SSL)
--capath DIR CA 证书目录 (SSL)
-E, --cert CERT[:PASSWD] 客户端证书文件及密码 (SSL)
--cert-type TYPE 证书文件类型 (DER/PEM/ENG) (SSL)
--ciphers LIST SSL 秘钥 (SSL)
--compressed 请求压缩 (使用 deflate 或 gzip)
-K, --config FILE 指定配置文件
--connect-timeout SECONDS 连接超时设置
-C, --continue-at OFFSET 断点续转
-b, --cookie STRING/FILE Cookies字符串或读取Cookies的文件位置 (H)
-c, --cookie-jar FILE 操作结束后,要写入 Cookies 的文件位置 (H)
--create-dirs 创建必要的本地目录层次结构
--crlf 在上传时将 LF 转写为 CRLF
--crlfile FILE 从指定的文件获得PEM格式CRL列表
-d, --data DATA HTTP POST 数据 (H)
--data-ascii DATA ASCII 编码 HTTP POST 数据 (H)
--data-binary DATA binary 编码 HTTP POST 数据 (H)
--data-urlencode DATA url 编码 HTTP POST 数据 (H)
--delegation STRING GSS-API 委托权限
--digest 使用数字身份验证 (H)
--disable-eprt 禁止使用 EPRT 或 LPRT (F)
--disable-epsv 禁止使用 EPSV (F)
-D, --dump-header FILE 将头信息写入指定的文件
--egd-file FILE 为随机数据设置EGD socket路径(SSL)
--engine ENGINGE 加密引擎 (SSL). "--engine list" 指定列表
-f, --fail 连接失败时不显示HTTP错误信息 (H)
-F, --form CONTENT 模拟 HTTP 表单数据提交(multipart POST) (H)
--form-string STRING 模拟 HTTP 表单数据提交 (H)
--ftp-account DATA 帐户数据提交 (F)
--ftp-alternative-to-user COMMAND 指定替换 "USER [name]" 的字符串 (F)
--ftp-create-dirs 如果不存在则创建远程目录 (F)
--ftp-method [MULTICWD/NOCWD/SINGLECWD] 控制 CWD (F)
--ftp-pasv 使用 PASV/EPSV 替换 PORT (F)
-P, --ftp-port ADR 使用指定 PORT 及地址替换 PASV (F)
--ftp-skip-pasv-ip 跳过 PASV 的IP地址 (F)
--ftp-pret 在 PASV 之前发送 PRET (drftpd) (F)
--ftp-ssl-ccc 在认证之后发送 CCC (F)
--ftp-ssl-ccc-mode ACTIVE/PASSIVE 设置 CCC 模式 (F)
--ftp-ssl-control ftp 登录时需要 SSL/TLS (F)
-G, --get 使用 HTTP GET 方法发送 -d 数据 (H)
-g, --globoff 禁用的 URL 队列 及范围使用 {} 和 []
-H, --header LINE 要发送到服务端的自定义请求头 (H)
-I, --head 仅显示响应文档头
-h, --help 显示帮助
-0, --http1.0 使用 HTTP 1.0 (H)
--ignore-content-length 忽略 HTTP Content-Length 头
-i, --include 在输出中包含协议头 (H/F)
-k, --insecure 允许连接到 SSL 站点,而不使用证书 (H)
--interface INTERFACE 指定网络接口/地址
-4, --ipv4 将域名解析为 IPv4 地址
-6, --ipv6 将域名解析为 IPv6 地址
-j, --junk-session-cookies 读取文件中但忽略会话cookie (H)
--keepalive-time SECONDS keepalive 包间隔
--key KEY 私钥文件名 (SSL/SSH)
--key-type TYPE 私钥文件类型 (DER/PEM/ENG) (SSL)
--krb LEVEL 启用指定安全级别的 Kerberos (F)
--libcurl FILE 命令的libcurl等价代码
--limit-rate RATE 限制传输速度
-l, --list-only 只列出FTP目录的名称 (F)
--local-port RANGE 强制使用的本地端口号
-L, --location 跟踪重定向 (H)
--location-trusted 类似 --location 并发送验证信息到其它主机 (H)
-M, --manual 显示全手动
--mail-from FROM 从这个地址发送邮件
--mail-rcpt TO 发送邮件到这个接收人(s)
--mail-auth AUTH 原始电子邮件的起始地址
--max-filesize BYTES 下载的最大文件大小 (H/F)
--max-redirs NUM 最大重定向数 (H)
-m, --max-time SECONDS 允许的最多传输时间
--metalink 处理指定的URL上的XML文件
--negotiate 使用 HTTP Negotiate 认证 (H)
-n, --netrc 必须从 .netrc 文件读取用户名和密码
--netrc-optional 使用 .netrc 或 URL; 将重写 -n 参数
--netrc-file FILE 设置要使用的 netrc 文件名
-N, --no-buffer 禁用输出流的缓存
--no-keepalive 禁用 connection 的 keepalive
--no-sessionid 禁止重复使用 SSL session-ID (SSL)
--noproxy 不使用代理的主机列表
--ntlm 使用 HTTP NTLM 认证 (H)
-o, --output FILE 将输出写入文件,而非 stdout
--pass PASS 传递给私钥的短语 (SSL/SSH)
--post301 在 301 重定向后不要切换为 GET 请求 (H)
--post302 在 302 重定向后不要切换为 GET 请求 (H)
--post303 在 303 重定向后不要切换为 GET 请求 (H)
-#, --progress-bar 以进度条显示传输进度
--proto PROTOCOLS 启用/禁用 指定的协议
--proto-redir PROTOCOLS 在重定向上 启用/禁用 指定的协议
-x, --proxy [PROTOCOL://]HOST[:PORT] 在指定的端口上使用代理
--proxy-anyauth 在代理上使用 "any" 认证方法 (H)
--proxy-basic 在代理上使用 Basic 认证 (H)
--proxy-digest 在代理上使用 Digest 认证 (H)
--proxy-negotiate 在代理上使用 Negotiate 认证 (H)
--proxy-ntlm 在代理上使用 NTLM 认证 (H)
-U, --proxy-user USER[:PASSWORD] 代理用户名及密码
--proxy1.0 HOST[:PORT] 在指定的端口上使用 HTTP/1.0 代理
-p, --proxytunnel 使用HTTP代理 (用于 CONNECT)
--pubkey KEY 公钥文件名 (SSH)
-Q, --quote CMD 在传输开始前向服务器发送命令 (F/SFTP)
--random-file FILE 读取随机数据的文件 (SSL)
-r, --range RANGE 仅检索范围内的字节
--raw 使用原始HTTP传输,而不使用编码 (H)
-e, --referer Referer URL (H)
-J, --remote-header-name 从远程文件读取头信息 (H)
-O, --remote-name 将输出写入远程文件
--remote-name-all 使用所有URL的远程文件名
-R, --remote-time 将远程文件的时间设置在本地输出上
-X, --request COMMAND 使用指定的请求命令
--resolve HOST:PORT:ADDRESS 将 HOST:PORT 强制解析到 ADDRESS
--retry NUM 出现问题时的重试次数
--retry-delay SECONDS 重试时的延时时长
--retry-max-time SECONDS 仅在指定时间段内重试
-S, --show-error 显示错误. 在选项 -s 中,当 curl 出现错误时将显示
-s, --silent Silent模式。不输出任务内容
--socks4 HOST[:PORT] 在指定的 host + port 上使用 SOCKS4 代理
--socks4a HOST[:PORT] 在指定的 host + port 上使用 SOCKSa 代理
--socks5 HOST[:PORT] 在指定的 host + port 上使用 SOCKS5 代理
--socks5-hostname HOST[:PORT] SOCKS5 代理,指定用户名、密码
--socks5-gssapi-service NAME 为gssapi使用SOCKS5代理服务名称
--socks5-gssapi-nec 与NEC Socks5服务器兼容
-Y, --speed-limit RATE 在指定限速时间之后停止传输
-y, --speed-time SECONDS 指定时间之后触发限速. 默认 30
--ssl 尝试 SSL/TLS (FTP, IMAP, POP3, SMTP)
--ssl-reqd 需要 SSL/TLS (FTP, IMAP, POP3, SMTP)
-2, --sslv2 使用 SSLv2 (SSL)
-3, --sslv3 使用 SSLv3 (SSL)
--ssl-allow-beast 允许的安全漏洞,提高互操作性(SSL)
--stderr FILE 重定向 stderr 的文件位置. - means stdout
--tcp-nodelay 使用 TCP_NODELAY 选项
-t, --telnet-option OPT=VAL 设置 telnet 选项
--tftp-blksize VALUE 设备 TFTP BLKSIZE 选项 (必须 >512)
-z, --time-cond TIME 基于时间条件的传输
-1, --tlsv1 使用 => TLSv1 (SSL)
--tlsv1.0 使用 TLSv1.0 (SSL)
--tlsv1.1 使用 TLSv1.1 (SSL)
--tlsv1.2 使用 TLSv1.2 (SSL)
--trace FILE 将 debug 信息写入指定的文件
--trace-ascii FILE 类似 --trace 但使用16进度输出
--trace-time 向 trace/verbose 输出添加时间戳
--tr-encoding 请求压缩传输编码 (H)
-T, --upload-file FILE 将文件传输(上传)到指定位置
--url URL 指定所使用的 URL
-B, --use-ascii 使用 ASCII/text 传输
-u, --user USER[:PASSWORD] 指定服务器认证用户名、密码
--tlsuser USER TLS 用户名
--tlspassword STRING TLS 密码
--tlsauthtype STRING TLS 认证类型 (默认 SRP)
--unix-socket FILE 通过这个 UNIX socket 域连接
-A, --user-agent STRING 要发送到服务器的 User-Agent (H)
-v, --verbose 显示详细操作信息
-V, --version 显示版本号并退出
-w, --write-out FORMAT 完成后输出什么
--xattr 将元数据存储在扩展文件属性中
-q .curlrc 如果作为第一个参数无效
1import openpyxl
2
3wb = openpyxl.Workbook()
4ws = wb.active
5ws.title = 'SheetName'
6wb.save("./filename.xlsx")
7
8wb.close()
1import openpyxl
2
3wb = openpyxl.Workbook()
4ws = wb.active
5ws.title = 'SheetName'
6
7ws = wb.creat_sheet("sheet1", 0)
8ws = wb.create_sheet("sheet2")
9
10wb.save("./filename.xlsx")
11
12wb.close()
1import openpyxl
2# step 1
3wb = openpyxl.Workbook()
4ws = wb.active
5ws.title = 'SheetName'
6
7# step 2
8ws = wb.creat_sheet("sheet1", 0)
9ws = wb.create_sheet("sheet2")
10
11# step 3
12ws['A1'] = 'Interfaces'
13ws['B1'] = 'Description'
14ws.cell(row=2, column=1, value='Gi1/0/1')
15ws.cell(row=3, column=1, value='Gi1/0/2')
16ws.cell(row=2, column=2, value='PC1')
17ws.cell(row=3, column=2, value='PC2')
18
19wb.save("./filename.xlsx")
20
21wb.close()
1import openpyxl
2# step 1
3wb = openpyxl.Workbook()
4ws = wb.active
5ws.title = 'SheetName'
6
7# step 2
8ws = wb.creat_sheet("sheet1", 0)
9ws = wb.create_sheet("sheet2")
10
11# step 3
12ws['A1'] = 'Interfaces'
13ws['B1'] = 'Description'
14ws.cell(row=2, column=1, value='Gi1/0/1')
15ws.cell(row=3, column=1, value='Gi1/0/2')
16ws.cell(row=2, column=2, value='PC1')
17ws.cell(row=3, column=2, value='PC2')
18
19# step 4
20a3 = ws1['A3']
21print (a3.value)
22
23column_A = ws1['A']
24for i in column_A:
25 print (i.value)
26
27row_3 = ws1[3]
28for i in row_3:
29 print (i.value)
30
31for row in ws1.iter_rows(min_row=1, max_col=2, max_row=3):
32 for cell in row:
33 print (cell.value)
34
35for row in ws1.values:
36 for value in row:
37 print (value)
38
39b3 = ws1['B3']
40b3.value = 'PC3'
41print (b3.value)
42
43wb.save("./filename.xlsx")
44
45wb.close()
1import openpyxl
2from openpyxl.styles import PatternFill, Border, Side
3
4# step 1
5wb = openpyxl.Workbook()
6ws = wb.active
7ws.title = 'SheetName'
8
9# step 2
10ws = wb.creat_sheet("sheet1", 0)
11ws = wb.create_sheet("sheet2")
12
13# step 3
14ws['A1'] = 'Interfaces'
15ws['B1'] = 'Description'
16ws.cell(row=2, column=1, value='Gi1/0/1')
17ws.cell(row=3, column=1, value='Gi1/0/2')
18ws.cell(row=2, column=2, value='PC1')
19ws.cell(row=3, column=2, value='PC2')
20
21# step 4
22a3 = ws1['A3']
23print (a3.value)
24
25column_A = ws1['A']
26for i in column_A:
27 print (i.value)
28
29row_3 = ws1[3]
30for i in row_3:
31 print (i.value)
32
33for row in ws1.iter_rows(min_row=1, max_col=2, max_row=3):
34 for cell in row:
35 print (cell.value)
36
37for row in ws1.values:
38 for value in row:
39 print (value)
40
41b3 = ws1['B3']
42b3.value = 'PC3'
43print (b3.value)
44
45# step 5
46yellowFill = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')
47thin_border = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin'))
48
49ws1['A1'].fill=yellowFill
50ws1['B1'].fill=yellowFill
51
52dims = {}
53for row in ws1.rows:
54 for cell in row:
55 cell.border=thin_border
56 if cell.value:
57 dims[cell.column_letter] = max((dims.get(cell.column, 0), len(str(cell.value))))
58
59for col, value in dims.items():
60 ws1.column_dimensions[col].width = value + 1
61
62
63wb.save("./filename.xlsx")
64
65wb.close()
开启本地代理安装PIP时, 有可能会有如下错误
1$ pip install wmi
2Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
3WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None))
4 after connection broken by 'ProxyError('Cannot connect to proxy.', FileNotFoundError(2, 'No such file or directory'))': /simple/wmi/
1[global]
2index-url = http://mirrors.aliyun.com/pypi/simple/
3[install]
4trusted-host = mirrors.aliyun.com
SQLAlchemy 是python中,通过ORM操作数据库的框架。简单点来说,就是帮助我们从烦冗的sql语句中解脱出来,从而不需要再去写原生的sql语句,只需要用python的语法来操作对象,就能被自动映射为sql语句。
pip install sqlalchemy
1# 导入:
2from sqlalchemy import Column, String, create_engine
3from sqlalchemy.orm import sessionmaker
4from sqlalchemy.ext.declarative import declarative_base
5
6# 创建对象的基类:
7Base = declarative_base()
8
9# 定义User对象:
10class User(Base):
11 # 表的名字:
12 __tablename__ = 'user'
13
14 # 表的结构:
15 id = Column(Integer, primary_key=True, autoincrement=True)
16 name = Column(String(20))
17
18# 初始化数据库连接:
19engine = create_engine('mysql+pymysql://root:root@localhost/tmpdb?charset=utf8')
20# 创建DBSession类型:
21DBSession = sessionmaker(bind=engine)
22# 创建session对象:
23session = DBSession()
24# 创建新User对象:
25new_user = User(id='5', name='Bob')
26# 添加到session:
27session.add(new_user)
28# 提交即保存到数据库:
29session.commit()
30# 关闭session:
31session.close()
1engine = create_engine('dialect+driver://username:password@host:port/database')
2# dialect:数据库类型
3# driver:数据库驱动选择
4# username:数据库用户名
5# password: 用户密码
6# host:服务器地址
7# port:端口
8# database:数据库
1# PostgreSQL
2engine = create_engine('postgresql://username:password@localhost/database')
3engine = create_engine('postgresql+psycopg2://username:password@localhost/database')
4engine = create_engine('postgresql+pg8000://username:password@localhost/database')
5
6# Mysql
7engine = create_engine('mysql://username:password@localhost/database')
8engine = create_engine('mysql+mysqldb://username:password@localhost/database')
9engine = create_engine('mysql+mysqlconnector://username:password@localhost/database')
10engine = create_engine('mysql+oursql://username:password@localhost/database')
11engine = create_engine('mysql+pymysql://username:password@localhost/database')
12
13# Oracle
14engine = create_engine('oracle://username:password@127.0.0.1:1521/database')
15engine = create_engine('oracle+cx_oracle://username:password@tnsname')
16
17# Microsoft SQL Server
18engine = create_engine('mssql+pyodbc://username:password@mydsn')
19engine = create_engine('mssql+pymssql://username:password@hostname:port/database')
20
21# SQLite
22engine = create_engine('sqlite:///database.db')
23engine = create_engine('sqlite:absolute/path/to/database.db')
# create_engine 其它可选参数
# echo :为 True 时候会把sql语句打印出来
# pool_size: 是连接池的大小,默认为5个,0表示连接数无限制
# pool_recycle: MySQL 默认情况下如果一个连接8小时内容没有任何动作(查询请求)就会自动断开链接,出现 MySQL has gone away的错误。设置了 pool_recycle 后 SQLAlchemy 就会在指定时间内回收连接。如果设置为3600 就表示 1小时后该连接会被自动回收。
# pool_pre_ping : 这是1.2新增的参数,如果值为True,那么每次从连接池中拿连接的时候,都会向数据库发送一个类似 select 1 的测试查询语句来判断服务器是否正常运行。当该连接出现 disconnect 的情况时,该连接连同pool中的其它连接都会被回收。
1# 获取元数据
2metadata = MetaData()
3# 定义表
4user = Table('user', metadata,
5 Column('id', Integer, primary_key=True),
6 Column('name', String(20)),
7 )
8
9color = Table('color', metadata,
10 Column('id', Integer, primary_key=True),
11 Column('name', String(20)),
12 )
13
14# 执行sql语句
15engine.execute(
16 "INSERT INTO db_name.color(id, name) VALUES ('1', 'liuyao');"
17)
18result = engine.execute('select * from color')
19print(result.fetchall())
1from sqlalchemy.ext.declarative import declarative_base
2from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index
3
4Base = declarative_base()
5
6
7class User(Base):
8 __tablename__ = 'user'
9 id = Column(Integer, primary_key=True, autoincrement=True)
10 name = Column(String(80))
11
12 def __repr__(self):
13 return '<User: {}>'.format(self.name)
14
15
16class Address(Base):
17 __tablename__ = 'address'
18 id = Column(Integer, primary_key=True, autoincrement=True)
19 email = Column(String(80))
20 user_id = Column(Integer, ForeignKey('user.id'))
21
22 def __repr__(self):
23 return "<Address %s %d>" % (self.email, self.user_id)
24
25
26# 清除已有表
27Base.metadata.drop_all(engine)
28# 建立表
29Base.metadata.create_all(engine)
30
31
1# 前置数据模型代码
2class User(Base):
3 __tablename__ = 'user'
4 id = Column(Integer, primary_key=True, autoincrement=True)
5 name = Column(String(40), unique=True, nullable=False)
6 email = Column(String(80), nullable=True)
7
8 def __repr__(self):
9 return "<User: %s, %s, %s>" % (self.id, self.name, self.email)
10
11 def to_dict(self):
12 return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}
13
14
15class Course(Base):
16 __tablename__ = 'course'
17 id = Column(Integer, primary_key=True, autoincrement=True)
18 name = Column(String(80))
19 # ForeignKey 设置外键关联,第一个参数为字符串,user 为数据表名,id 为字段名
20 # 第二个参数 ondelete 设置删除 User 实例后对关联的 Course 实例的处理规则
21 # 'CASCADE' 表示级联删除,删除用户实例后,对应的课程实例也会被连带删除
22 user_id = Column(Integer, ForeignKey('user.id', ondelete='CASCADE'))
23 # relationship 设置查询接口,以便后期进行数据库查询操作
24 # 第一个参数为位置参数,参数值为外键关联的映射类名,数据类型为字符串
25 # 第二个参数 backref 设置反向查询接口
26 # backref 的第一个参数 'course' 为查询属性,User 实例使用该属性可以获得相关课程实例的列表
27 # backref 的第二个参数 cascade 如此设置即可实现 Python 语句删除用户数据时级联删除课程数据
28 user = relationship('User',
29 backref=backref('course', cascade='all, delete-orphan'))
30
31 def __repr__(self):
32 return '<Course: %s, %s, %s>' % (self.id, self.name, self.user_id)
33
34 def to_dict(self):
35 return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}
36
37
38class Address(Base):
39 __tablename__ = "address"
40 id = Column(Integer, primary_key=True, autoincrement=True, comment='主键')
41 user_id = Column(Integer, nullable=False, comment='用户ID')
42 addr = Column(String(200), nullable=True)
43
44 def __repr__(self):
45 return '<Address %s, %s>' % (self.user_id, self.addr)
46
47 def to_dict(self):
48 return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}
1userquery = session.query(User)
2lst = [
3 # 条件查询
4 userquery.filter(User.id > 3).all(),
5 userquery.filter(User.id > 4).all()[:3],
6 session.query(User.name).filter(User.id > 4).all(),
7 userquery.filter(User.id == 3).first(),
8 userquery.filter(User.id == 5).one(),
9 userquery.filter(User.id.between(3,6)).all(),
10 # 限制返回条数
11 userquery.filter(User.id > 0).all(),
12 userquery.filter(User.id > 0).limit(2).all(),
13 userquery.filter(User.id > 0).offset(2).all(),
14 userquery.filter(User.id > 0).slice(2, 3).all(),
15 # 条件排序
16 userquery.filter(User.id > 0).order_by(User.id).all(),
17 userquery.filter(User.id > 0).order_by(desc(User.id)).all(),
18 userquery.filter(User.id > 0).order_by(User.id.asc()).all(),
19 userquery.filter(User.id > 0).order_by(User.id.desc()).all(),
20 # 不等于
21 userquery.filter(User.id != 3).all(),
22 # 模糊匹配 like, not like
23 userquery.filter(User.email.like('%ao%')).all(),
24 userquery.filter(User.email.notlike('%ao%')).all(),
25 # 匹配
26 userquery.filter(User.email.startswith("a")).all(),
27 userquery.filter(User.email.endswith("g")).all(),
28 userquery.filter(User.email.contains("ao")).all(),
29 # 属于in_ 不属于 notin_
30 userquery.filter(User.id.in_([1, 3, 5])).all(),
31 userquery.filter(User.id.notin_((1, 3, 5))).all(),
32 # 空判断
33 userquery.filter(User.name == None).all(),
34 userquery.filter(User.name.is_(None)).all(),
35 userquery.filter(User.name.isnot(None)).all(),
36 # 多条件
37 userquery.filter(User.id > 3, User.id < 5).all(),
38 userquery.filter(User.id > 3).filter(User.id < 5).all(),
39 # 选择条件
40 userquery.filter(or_(User.id < 2, User.id > 9)).all(),
41 userquery.filter(and_(User.id > 3, User.id < 6)).all(),
42 # 去重
43 userquery.filter(User.id > 3).distinct().all(),
44 # 聚合函数
45 session.query(Course.user_id, func.count(Course.user_id).label('number')).group_by(Course.user_id).all(),
46 session.query(Course.user_id, func.count(Course.user_id).label('number')).group_by(Course.user_id).having(func.count(Course.user_id) > 1).all(),
47 session.query(Course.user_id, func.sum(Course.user_id).label('number')).group_by(Course.user_id).all(),
48 session.query(Course.user_id, func.max(Course.user_id).label('number')).group_by(Course.user_id).all(),
49 session.query(Course.user_id, func.min(Course.user_id).label('number')).group_by(Course.user_id).all(),
50 # 使用extract提取时间中的分钟或者天来分组
51 session.query(extract('minute', User.creatime).label('minute'), func.count('*').label('count')).group_by('minute').all(),
52 session.query(extract('day', User.creatime).label('day'), func.count('*').label('count')).group_by('day').all(),
53 # Join
54 有外键
55 session.query(User.id, User.name.label('uname'), Course.name.label("cname")).join(Course).filter(User.id > 4).all(),
56 无外键, 指定关联关系
57 session.query(User.id, User.name, Address.addr).join(Address, User.id == Address.user_id).filter(User.id > 5).all(),
58 # text 直接写sql
59 userquery.filter(text("id>:id")).params(id=4).all(),
60
61]
62
63# 外连接
64smtp = session.query(User).filter(User.id > 5).subquery()
65lst.append(session.query(smtp.c.name, Address.addr).outerjoin(smtp, Address.user_id == smtp.c.id).all())
66
67
68for res in lst:
69 print(res)
70 # 单对象
71 # data = [r.to_dict() for r in res]
72 # print(data)
73 # 多表查询时
74 # data = [dict(zip(result.keys(), result)) for result in res]
75 # print(data)
76 print("*" * 30)
1class Blog(Base):
2 __tablename__ = 'blog'
3
4 id = Column(BIGINT, primary_key=True, autoincrement=True)
5 title = Column(String(64), server_default='', nullable=False)
6 text = Column(Text, nullable=False)
7 user = Column(BIGINT, nullable=False) # Column(BIGINT, ForeignKey('user.id'), index=True, nullable=False)
8 create = Column(BIGINT, index=True, server_default='0', nullable=False)
9
10 def __repr__(self):
11 return '<Course: %s, %s, %s>' % (self.id, self.title, self.user)
12
13class User(Base):
14 __tablename__ = 'user'
15
16 id = Column(BIGINT, primary_key=True, autoincrement=True)
17 name = Column(String(32), server_default='', nullable=False)
18 username = Column(String(32), index=True, server_default='', nullable=True)
19 password = Column(String(64), server_default='', nullable=False)
20
21 def __repr__(self):
22 return '<Course: %s, %s, %s>' % (self.id, self.name, self.username)
23
24
25# 查询
26print( session.query(User).all() )
27pirnt( session.query(Blog).all() )
28print( session.query(Blog).join(User, user.id==Blog.user).all() )
1class Blog(Base):
2 __tablename__ = 'blog'
3
4 id = Column(BIGINT, primary_key=True, autoincrement=True)
5 title = Column(String(64), server_default='', nullable=False)
6 text = Column(Text, nullable=False)
7 user = Column(BIGINT, ForeignKey('user.id'), index=True, nullable=False)
8 create = Column(BIGINT, index=True, server_default='0', nullable=False)
9
10 def __repr__(self):
11 return '<Course: %s, %s, %s>' % (self.id, self.title, self.user)
12
13class User(Base):
14 __tablename__ = 'user'
15
16 id = Column(BIGINT, primary_key=True, autoincrement=True)
17 name = Column(String(32), server_default='', nullable=False)
18 username = Column(String(32), index=True, server_default='', nullable=True)
19 password = Column(String(64), server_default='', nullable=False)
20
21 def __repr__(self):
22 return '<Course: %s, %s, %s>' % (self.id, self.name, self.username)
23
24
25# 查询
26print( session.query(User).all() )
27pirnt( session.query(Blog).all() )
28print( session.query(Blog).join(User).filter(User.id==3).all() )
1# backref 只要一边写上就可以
2class User(Base):
3 __tablename__ = 'user'
4 id = Column(Integer, primary_key=True, autoincrement=True)
5 name = Column(String(80))
6
7 addresses = relationship("Address", backref="user")
8
9 def __repr__(self):
10 return '<User: {}>'.format(self.name)
11
12
13class Address(Base):
14 __tablename__ = 'address'
15 id = Column(Integer, primary_key=True, autoincrement=True)
16 email = Column(String(80))
17 user_id = Column(Integer, ForeignKey('user.id'))
18
19 def __repr__(self):
20 return "<Address %s %d>" % (self.email, self.user_id)
21
22# back_populates 要两边都写上
23class User(Base):
24 __tablename__ = 'user'
25 id = Column(Integer, primary_key=True, autoincrement=True)
26 name = Column(String(80))
27
28 addresses = relationship("Address", back_populates="user")
29
30 def __repr__(self):
31 return '<User: {}>'.format(self.name)
32
33
34class Address(Base):
35 __tablename__ = 'address'
36 id = Column(Integer, primary_key=True, autoincrement=True)
37 email = Column(String(80))
38 user_id = Column(Integer, ForeignKey('user.id'))
39
40 user = relationship("User", back_populates="addresses")
41
42 def __repr__(self):
43 return "<Address %s %d>" % (self.email, self.user_id)
44
45# 查询
46
47user = session.query(User).get(3)
48print(user, user.address)
49addr = session.qeury(Address).get(3)
50print(addr, addr.user)
1class Parent(Base): # 一
2 __tablename__ = 'parent'
3 id = Column(Integer, primary_key=True)
4 name = Column(String(64), nullable=False)
5 children = relationship("Child", backref=backref('parents'))
6
7
8class Child(Base): # 多
9 __tablename__ = 'child'
10 id = Column(Integer, primary_key=True)
11 name = Column(String(64), nullable=False)
12 parent_id = Column(Integer, ForeignKey('parent.id'))
13
14# 一对多 一方
15# children = relationship("Child", backref=backref('parents'), cascade="all, delete-orphan")
16# 一对多 多方
17# parents = relationship("Parent", backref=backref('children', cascade="all, delete-orphan"))
18# 以上可以级联删除
1
1
pip install Faker
from faker import Faker # 1
fake = Faker() # 2
fake.name() # 3
# Donna Kelly
fake.address() # 4
# 519 Donna River
from faker import Faker
fake = Faker(locale='zh_CN')
fake.name()
# 庞超
fake.address()
# 河北省辛集县合川张街p座 489476
fake.address() # 地址
# '香港特别行政区大冶县上街钟街k座 664713'
fake.building_number() # 楼名
# 'v座'
fake.city() # 完整城市名
# '长春县'
fake.city_name() # 城市名字(不带市县)
# '梧州'
fake.city_suffix() # 城市后缀名
# '市'
fake.country() # 国家名称
# '厄立特里亚'
fake.country_code(representation="alpha-2")
# 'BZ' # 国家编号
fake.district() # 地区
# '沙湾'
fake.postcode() # 邮编
# '332991'
fake.province() # 省
# '河北省'
fake.street_address() # 街道地址
# '武汉街D座'
fake.street_name() # 街道名称
# '广州路'
fake.street_suffix() # 街道后缀名
# '路'
汽车相关
fake.license_plate() # 牌照
# 'ZCO 000'
fake.bank_country() # 银行所属国家
# 'GB'
fake.bban() # 基本银行账号
# 'TPET9323218579379'
fake.iban() # 国际银行代码
# 'GB82IRVM1531009974701'
fake.ean(length=13) # EAN条形码
# '5456457843465'
fake.ean13() # EAN13条形码
# '2689789887590'
fake.ean8() # EAN8条形码
# '52227936'
fake.color_name() # 颜色名称
# 'Orange'
fake.hex_color() # 颜色十六进制值
# '#a5cb7c'
fake.rgb_color() # 颜色RGB值
# '15,245,42'
fake.rgb_css_color() # CSS颜色值
# 'rgb(15,70,13)'
fake.safe_color_name() # 安全色
# 'aqua'
fake.safe_hex_color() # 安全色十六进制值
# '#881100'
fake.bs() # 商业用词
# 'synthesize strategic vortals'
fake.catch_phrase() # 妙句(口号)
# 'Robust even-keeled service-desk'
fake.company() # 公司名称
# '富罳科技有限公司'
fake.company_prefix() # 公司名称前缀
# '商软冠联'
fake.company_suffix() # 公司名称后缀
# '网络有限公司'
fake.credit_card_expire(start="now", end="+10y", date_format="%m/%y") # 过期年月
# '11/20'
fake.credit_card_full(card_type=None) # 完整信用卡信息
# 'VISA 16 digit\n秀珍 卢\n4653084445257690 11/19\nCVC: 935\n'
fake.credit_card_number(card_type=None) # 信用卡卡号
# '4339481813664365360'
fake.credit_card_provider(card_type=None) # 信用卡提供商
# 'VISA 19 digit'
fake.credit_card_security_code(card_type=None) # 信用卡安全码
# '597'
fake.cryptocurrency() # 加密货币代码+名称
# ('TRX', 'TRON')
fake.cryptocurrency_code() # 加密货币代码
# 'MZC'
fake.cryptocurrency_name() # 加密货币名称
# 'Ripple'
fake.currency() # 货币代码+名称
# ('GNF', 'Guinean franc')
fake.currency_code() # 货币代码
# 'SOS'
fake.currency_name() # 货币名称
# 'Lebanese pound'
fake.am_pm() # AM或PM
# 'PM'
fake.century() # 世纪
# 'XII'
fake.date(pattern="%Y-%m-%d", end_datetime=None) # 日期字符串(可设置格式和最大日期)
# '1998-05-13'
fake.date_between(start_date="-30y", end_date="today") # 日期(可设置限定范围)
# datetime.date(2014, 8, 17)
fake.date_between_dates(date_start=None, date_end=None) # 同上
# datetime.date(2019, 10, 14)
fake.date_object(end_datetime=None) # 日期(可设置最大日期)
# datetime.date(1981, 12, 20)
fake.date_of_birth(tzinfo=None, minimum_age=0, maximum_age=115) # 出生日期
# datetime.date(1931, 12, 8)
fake.date_this_century(before_today=True, after_today=False) # 本世纪日期
# datetime.date(2003, 5, 4)
fake.date_this_decade(before_today=True, after_today=False) # 本年代中的日期
# datetime.date(2014, 1, 29)
fake.date_this_month(before_today=True, after_today=False) # 本月中的日期
# datetime.date(2019, 10, 10)
fake.date_this_year(before_today=True, after_today=False) # 本年中的日期
# datetime.date(2019, 3, 6)
fake.date_time(tzinfo=None, end_datetime=None) # 日期和时间
# datetime.datetime(1990, 8, 11, 22, 25)
fake.date_time_ad(tzinfo=None, end_datetime=None, start_datetime=None) # 日期和时间(从001年1月1日到现在)
# datetime.datetime(244, 12, 17, 9, 59, 56)
fake.date_time_between(start_date="-30y", end_date="now", tzinfo=None) # 日期时间(可设置限定范围)
# datetime.datetime(1995, 4, 19, 17, 23, 51)
fake.date_time_between_dates(datetime_start=None, datetime_end=None, tzinfo=None) # 同上
# datetime.datetime(2019, 10, 14, 14, 15, 36)
fake.date_time_this_century(before_now=True, after_now=False, tzinfo=None) # 本世纪中的日期和时间
# datetime.datetime(2009, 8, 26, 18, 27, 9)
fake.date_time_this_decade(before_now=True, after_now=False, tzinfo=None) # 本年代中的日期和时间
# datetime.datetime(2019, 2, 24, 22, 18, 44)
fake.date_time_this_month(before_now=True, after_now=False, tzinfo=None) # 本月中的日期和时间
# datetime.datetime(2019, 10, 3, 9, 20, 44)
fake.date_time_this_year(before_now=True, after_now=False, tzinfo=None) # 本年中的日期和时间
# datetime.datetime(2019, 2, 10, 7, 3, 18)
fake.day_of_month() # 几号
# '23'
fake.day_of_week() # 星期几
# 'Tuesday'
fake.future_date(end_date="+30d", tzinfo=None) # 未来日期
# datetime.date(2019, 10, 28)
fake.future_datetime(end_date="+30d", tzinfo=None) # 未来日期和时间
# datetime.datetime(2019, 10, 28, 21, 4, 35)
fake.iso8601(tzinfo=None, end_datetime=None) # iso8601格式日期和时间
# '1995-04-10T00:45:01'
fake.month() # 第几月
# '07'
fake.month_name() # 月份名称
# 'December'
fake.past_date(start_date="-30d", tzinfo=None) # 过去日期
# datetime.date(2019, 10, 3)
fake.past_datetime(start_date="-30d", tzinfo=None) # 过去日期和时间
# datetime.datetime(2019, 9, 30, 20, 25, 43)
fake.time(pattern="%H:%M:%S", end_datetime=None) # 时间(可设置格式和最大日期时间)
# '14:26:44'
fake.time_delta(end_datetime=None) # 时间间隔
# datetime.timedelta(0)
fake.time_object(end_datetime=None) # 时间(可设置最大日期时间)
# datetime.time(4, 41, 39)
fake.time_series(start_date="-30d", end_date="now", precision=None, distrib=None, tzinfo=None)
# <generator object Provider.time_series at 0x7fadf51e0930>
fake.timezone() # 时区
# 'Asia/Baku'
fake.unix_time(end_datetime=None, start_datetime=None) # UNIX时间戳
# 393980728
fake.year() # 某年
# '2016'
fake.file_extension(category=None) # 文件扩展名
# 'avi'
fake.file_name(category=None, extension=None) # 文件名
# '专业.pptx'
fake.file_path(depth=1, category=None, extension=None) # 文件路径
# '/的话/以上.ods'
fake.mime_type(category=None) # MIME类型
# 'application/xop+xml'
fake.unix_device(prefix=None) # UNIX设备
# '/dev/xvdq'
fake.unix_partition(prefix=None) # UNIX分区
# '/dev/xvdc6'
fake.coordinate(center=None, radius=0.001) # 坐标
# Decimal('147.543284')
fake.latitude() # 纬度
# Decimal('66.519139')
fake.latlng() # 经纬度
# (Decimal('55.3370965'), Decimal('-15.427896'))
fake.local_latlng(country_code="US", coords_only=False) # 返回某个国家某地的经纬度
# ('25.67927', '-80.31727', 'Kendall', 'US', 'America/New_York')
fake.location_on_land(coords_only=False) # 返回地球上某个位置的经纬度
# ('42.50729', '1.53414', 'les Escaldes', 'AD', 'Europe/Andorra')
fake.longitude() # 经度
# Decimal('70.815233')
fake.ascii_company_email(*args, **kwargs) # 企业邮箱(ascii编码)
# 'qiuyan@xiulan.cn'
fake.ascii_email(*args, **kwargs) # 企业邮箱+免费邮箱(ascii编码)
# 'lei59@78.net'
fake.ascii_free_email(*args, **kwargs) # 免费邮箱(ascii编码)
# 'pcheng@gmail.com'
fake.ascii_safe_email(*args, **kwargs) # 安全邮箱(ascii编码)
# 'fangyan@example.org'
fake.company_email(*args, **kwargs) # 企业邮箱
# 'scao@pingjing.net'
fake.domain_name(levels=1) # 域名
# 'dy.cn'
fake.domain_word(*args, **kwargs) # 二级域名
# 'gangxiuying'
fake.email(*args, **kwargs) # 企业邮箱+免费邮箱
# 'na13@ding.cn'
fake.free_email(*args, **kwargs) # 免费邮箱
# 'fang48@hotmail.com'
fake.free_email_domain(*args, **kwargs) # 免费邮箱域名
# 'yahoo.com'
fake.hostname(*args, **kwargs) # 主机名
# 'lt-70.53.cn'
fake.image_url(width=None, height=None) # 图片URL
# 'https://placekitten.com/752/243'
fake.ipv4(network=False, address_class=None, private=None) # ipv4
# '160.152.149.78'
fake.ipv4_network_class() # ipv4网络等级
# 'b'
fake.ipv4_private(network=False, address_class=None) # 私有ipv4
# '10.99.124.57'
fake.ipv4_public(network=False, address_class=None) # 公共ipv4
# '169.120.29.235'
fake.ipv6(network=False) # ipv6
# 'f392:573f:d60f:9aed:2a4c:36d7:fe5b:7034'
fake.mac_address() # MAC地址
# '62:67:79:8c:c2:40'
fake.safe_email(*args, **kwargs) # 安全邮箱
# 'jing58@example.org'
fake.slug(*args, **kwargs) # URL中的slug
# ''
fake.tld() # 顶级域名
# 'cn'
fake.uri() # URI
# 'http://yi.com/list/main/explore/register.php'
fake.uri_extension() # URI扩展
# '.php'
fake.uri_page() # URI页
# 'terms'
fake.uri_path(deep=None) # URI路径
# 'blog/tags/blog'
fake.url(schemes=None) # URL
# 'http://liutao.cn/'
fake.user_name(*args, **kwargs) # 用户名
# 'xiulan80'
fake.isbn10(separator="-") # ISBN-10图书编号
# '0-588-73943-X'
fake.isbn13(separator="-") # ISBN-13图书编号
# '978-1-116-51399-8'
fake.job() # 职位
# '法务助理'
fake.paragraph(nb_sentences=3, variable_nb_sentences=True, ext_word_list=None) # 单个段落
# '最新事情生产.方面解决名称责任而且.类型其实内容发生电脑.音乐具有今年是一.'
fake.paragraphs(nb=3, ext_word_list=None) # 多个段落
# ['使用评论管理.没有广告工作评论是否.', '帖子而且专业.这些比较完全发现准备设计工具.', '完成详细发生空间汽车.新闻电影您的游戏这种操作网站知道.']
fake.sentence(nb_words=6, variable_nb_words=True, ext_word_list=None) # 单个句子
# '直接这样点击单位对于时候.'
fake.sentences(nb=3, ext_word_list=None) # 多个句子
# ['电话国际项目管理.', '软件之后提高一样次数电影规定.', '东西会员发展什么不断经济.']
fake.text(max_nb_chars=200, ext_word_list=None) # 单个文本
# ('资源信息得到因此开发资源资料.\n'
# '国家这样等级需要用户如此.电话非常一切游戏所以学校类型.不要正在如果来源认为投资在线.\n'
# '这些更新密码其中起来实现有些.以上事情重要通过.\n'
# '但是就是介绍最大深圳简介设计.历史这种可以出现中心社区.\n'
# '政府当然包括简介全国内容生活.有些地址以上.回复这些来自搜索现在不断经营不断.\n'
# '操作为什孩子报告东西拥有如此.相关特别业务日本这种.合作问题准备比较谢谢.')
fake.texts(nb_texts=3, max_nb_chars=200, ext_word_list=None) # 多个文本
# [ '地址控制无法正在必须中心积分一些.支持制作安全.\n'
# '比较最新最大她的功能能够是一.主题选择当前显示.\n'
# '的话社会现在地区阅读继续所有.美国数据正在深圳不能.\n'
# '能够查看其中生活商品.谢谢认为之后以及以下之后这里.\n'
# '活动支持人民这么今年.要求包括生活运行技术社会.\n'
# '当前更多游戏.下载一点开发论坛法律为了美国.\n'
# '如何更新个人谢谢作为还有论坛.销售销售法律学生这么责任一些.',
# '日本最大方法活动主题到了结果.教育还有孩子觉得简介出现国际.东西国家图片威望品牌.\n'
# '那些会员现在准备可能.威望部分文件主题东西业务一切之间.所以必须当前方法.\n'
# '等级大小重要可能下载孩子.来源感觉业务文件以后深圳学校.网络什么新闻都是安全.\n'
# '资料重要成功谢谢时候音乐安全相关.电脑系列日期.工具使用搜索来源首页.\n'
# '直接企业影响大小什么.相关品牌选择她的规定来源推荐.',
# '中文文化数据内容系统.他们这些之间深圳.\n'
# '联系城市出现部分都是政府生活.社会同时人民市场现在决定需要.其他政府简介深圳教育加入对于.\n'
# '运行是一语言安全通过大小学生.商品然后信息由于虽然.\n'
# '因为关于选择希望行业具有深圳.出现价格那么下载提高知道人员.设备直接显示事情帖子正在两个关于.\n'
# '系列公司大家.论坛所以完全文章标准.活动中国工具电脑.\n'
# '主题作者不能.进行国家系统地区增加.经验质量价格我的.']
fake.word(ext_word_list=None) # 单个词语
# '新闻'
fake.words(nb=3, ext_word_list=None, unique=False) # 多个词语
# ['选择', '历史', '规定']
fake.binary(length=1048576) # 二进制
# (b'\xbf\xce\x01Y:\xf7\xf4\xe0G]\x94*Rb\x9f\x85\xb6\xcd\x83\x15\t\xbc\x16\x8d'
# b'\xcb\n\x90\x10S\x1e85\x91\xae\x06\xbdq.\xf6c\x1f\xfd\x94=\\\xf9_\xc2'
# b't\xe0{\x15\xd9\x8fW7\xe5[\x0b\x84\xd2\x94\xf4\xd91\xd2\x91\x01\xb5\xeej\x84'
# b'*\x81\x96\xa7\xa9\xda\x1f\xee\x9a\xb0\x1d\xef\xad\x92\x1c\x0f\xa0U6\xaf'
# b'x5\x9f\x93\\b \xf7kq\xfe\x97(\xe0Q\x89*\xbb\x8b\x9a\x14\xd2\xfe\x07'
# b'\xfe\xcfYy\x16\x12\xef\xe3\xd9%\x95\\\x80O\xec\x9f\xf7\x88\xfal'
# b'\x11\x93\x94\xb1\xd9\xf6b\xf0\x7f\xa2\x95\x93[\x98\xf3\xe0$\xdd\xe0D'
# b'\xde\x8c\xe3\xe0\xc0f\xab\x1c\xf6\xdf]\xbe8U\x11\xc7\xce\xf6f\xc9'
# b'1\xa6\xda\x85\xe6.\xda\xd1_\x8a\xbe\x05\xbf\xf4*x [\xb9\xc3\xbb\x99\xa1\xbe'
# b'GT\xb75\x96\x8a\x9a:`o\x1bm\xe9KzT\x0c\xdc\xb1\xe7ssiN\xcb2\x8eY'
# b'\xd1\xb4\x8c+\xe9\xc1Ph\x0fD\x0f\xd5}\n/K$\x85J\xaf\x1d\xb2\xd0R\xa7n0l'
# b'\xafQ\x91\x95\xac]a\xe1\x8f\x1f\x9e`e\xd2\x1f\xaa\xeb\xf3[}(\xd60\x01'
# b'Y\r\xe2XCW\xba\xa3\xad\xe4OP\x891=\xff\xae\xb9\x9d\xa2!\xfa2\r\x81\xfat\xfb'
# b'3t%\xd5\x11B\x94Os\x8d\xc5\xae%\xa6\x93}[p\x02\xd7\xba\xa4\xf0?R\xbb\xf6\xb1'
# b'h\x12J\x05\xce\xf9\xcd\xc6\xa7\xed\x80\x9e\x9e\xf8q]\xab\x9a\xd7\xd6'
# b'\xad\xecK\x1d=\xb0?\xb2\x83\t<\xb2ZGl\x9f\x8dmI\x1d\xf1jh\xd3s\x9d\xd6\xf9'
# b'\x8e\xbfs\xa9_\xe0\xaf\x86O\xde|\x17\xb5\x8b\xe4:Z\xa1\x01f\xc9l[Z'
# b'\xb4\x7fS\x0f7\x9c\x9d\xdd\xd3PY\x86\xf4\xec\xcb\x87\x05\xafU-\xaebY~'
# b"\x9f\xec\xf6\x9c\x84\x99'S\xd4\t.\xd0x\xbb\x01<&\xdd\xfc6M\xa9|R"
# b'\xec\xf9b\xcdz\x9a\x97p\xb5\xb6\x13\xd9\xab\x91C\xe4\x95\xc9\x18\xaeAi\\N'
# b"#\x99\t+Z\xd2\xf1\x89\xa0L\x04\xef\xaf<\xc4\xfbO\xcd\x83\xd4\x17'C\x10"
# b'\x0b\xd6\xb5Cv\x98}E\xc9;\xbf\x05\xab\xc7 W\xa8\xbcmX\x06\x865\xbe\\f\xedc'
# b'\xacb\xc8\x84\xc0KI\xd5\xea\x888\x93^\xfcE\xee,^(\x97g\xd17\xcd8\xabU\x95'
# b'\x17~]\x08\x11\xa4\xbf\xed\xf3\xabm\x15l\xde\xf5\x06c\xe1\xad+'
# b'\xed\xd1\xa5\xda\x15\xbax\xac}\x8e\xd7\x8831\x04\xb3\xae\xc7\xb4\x04'
# b'y\xda!\xeb\x1e\xcd\n+\x94#4\xe51\xc8\xe9t\n.:\xfd\xcfc\x1a\xcf\x99VY\x11'
# b'Y\x1bF\xe9\x9e\xebK\x86WD\x80\x12\xf1\x11z\xf6\xe3vV4\xbcB\n^k(\x1aw'
# b'<\xfd\x95z\t\xf7\xaa_F%n\xc4\xeb\x94\xcd\x80\xffh\xbe{^\x04\xe3\xe7'
# b'\xab\xa3\xd9\x037\x86\xde~J\x15th\x98_\xda\xe25\xeaO\xc8\x15\xae\xd7\xa9'
# b'\x80\x9as\xef<FU\xb2\x10\x7fN\x05\x8dd_\xef\x0bQO-\x9diW\xdc\xcdV\xbe*'
# b'\x13\xa7$\x08\xe4\xb8\x96bd\xcf\xe7\xd6h\xe9.{Z:S\xef\xc4\x14R\x91'
# b"\xce\xd3\xcd\xe3\xbc\x9f!Y\x05A\xa00\x11\xca\xaa\xeb\xc4')\xb3\xdcF\x8e\xfa"
# b'\xbd\x9b:\xae\x1f\xbe<7]\x93E\xc2\x1b\x17\xc95x\x8f\x88|\xb8^\xea\x06'
# b'(\x9d\xc5\xeb\x8a|\x9f\x05\x83\xfe\xf5KsUy\xdc\xd1S\x96\xda\xc5q\xc4\xfd'
# b'\xeb\xc4"\x14Y\x1cU\x99\xe8\x11r\x04\x941\xa1\xac^c\xbbG\xc4\xd8\xb70'
# b'\xadX\x98\xad\xf8\xc1\x11\x10\xbc\x00\x80\x84\x05\x07b\x8c0\x93\xe6\xd8'
# b'\xe2I\xea\xecm+-\x8aY\xb8F\x0e\x19#zH{/\xcb\x88\xac\xa9\xfe\x84cH[_'
# b'0d\xc6\xc4\x0b\r\x9ef\n\xb3\x97d\xb4;\xf1\x014kv\xd9h\xad\x18/\xe6\xf1r\xa1'
# b'3\x9cz\xf7\x90\r\xaf\xed\x85\x07\x80\xbb\xc2\x82\xe4\xcc\x91\xc8\xdf\x9a'
# b'`St\xd8\x98\xbb\xac\xe9\x93\xe0*\xd7\x9b/)\x93\x08\xc1\x0cxhD\xd2\xf1'
# b'\xbe5\xe1\x1f:\x04\x07\xf1\xb4\xaeJ\xe2\xe0[\x9e\xa4\x9b\xed)\xbf\xc2}+\x88'
# b'\x08I^f\x82-\xa2o\xb2\xc3\x85\xc5;Z\x13B\xf76~\x9af\xf7\xa9\x1a\xa4\xd4\xb8b')
fake.boolean(chance_of_getting_true=50) # 布尔值
# True
fake.md5(raw_output=False) # Md5
# '0712ca7a3be00aa01c823de37dc61230'
fake.null_boolean() # NULL+布尔值
# True
fake.password(length=10, special_chars=True, digits=True, upper_case=True, lower_case=True) # 密码
# '^7cSoHR1^r'
fake.sha1(raw_output=False) # SHA1
# 'f89f039d9fc00860651d9a567ac27990ae609445'
fake.sha256(raw_output=False) # SHA256
# '675a85aa0d29583200f75351e35b4af0335af835fc617382cbd9fece258b6520'
fake.uuid4(cast_to=<class 'str'>) # UUID4
# '0d7be36a-febd-4f9f-bf1e-791c0ee1227b'
fake.first_name() # 名字
# '强'
fake.first_name_female() # 名字(女)
# '桂荣'
fake.first_name_male() # 名字(男)
# '志强'
fake.first_romanized_name() # 名字(罗马文)
# 'Chao'
fake.last_name() # 姓
# '宋'
fake.last_name_female() # 姓(女)
# '陆'
fake.last_name_male() # 姓(男)
# '曾'
fake.last_romanized_name() # 姓(罗马文)
# 'Xie'
fake.name() # 姓名
# '王凯'
fake.name_female() # 姓名(女)
# '戴丽丽'
fake.name_male() # 姓名(男)
# '刘荣'
fake.prefix() # 称谓
# ''
fake.prefix_female() # 称谓(女)
# ''
fake.prefix_male() # 称谓(男)
# ''
fake.romanized_name() # 称谓(罗马文)
# 'Guiying Chang'
fake.suffix() # 姓名后缀(中文不适用)
# ''
fake.suffix_female()
# ''
fake.suffix_male()
# ''
fake.msisdn() # 完整手机号码(加了国家和国内区号)
# '9067936325890'
fake.phone_number() # 手机号
# '18520149907'
fake.phonenumber_prefix() # 区号
# 145
fake.profile(fields=None, sex=None) # 档案(完整)
# { 'address': '河南省昆明市清河哈尔滨路H座 496152',
# 'birthdate': datetime.date(2014, 11, 20),
# 'blood_group': 'AB+',
# 'company': '易动力信息有限公司',
# 'current_location': (Decimal('77.504143'), Decimal('-167.365806')),
# 'job': '培训策划',
# 'mail': 'liangyang@yahoo.com',
# 'name': '杨磊',
# 'residence': '澳门特别行政区台北县西夏兴城街L座 803680',
# 'sex': 'F',
# 'ssn': '140722200004166520',
# 'username': 'lei65',
# 'website': [ 'http://www.29.cn/',
# 'http://www.lei.cn/',
# 'http://lishao.net/',
# 'https://www.feng.net/']}
fake.simple_profile(sex=None) # 档案(简单)
# { 'address': '广西壮族自治区南宁市花溪孙街c座 653694',
# 'birthdate': datetime.date(1993, 12, 16),
# 'mail': 'haomin@yahoo.com',
# 'name': '任秀英',
# 'sex': 'F',
# 'username': 'iding'}
fake.pybool() # Python布尔值
# False
fake.pydecimal(left_digits=None, right_digits=None, positive=False, min_value=None, max_value=None) # Python十进制数
# Decimal('-837022273798.0')
fake.pydict(nb_elements=10, variable_nb_elements=True, *value_types) # Python字典
# { '一种': 6381,
# '可以': -9242847.69292,
# '地址': 9668,
# '拥有': 'jVBverSGAJvHsrcZPFDg',
# '控制': Decimal('-98521.0'),
# '本站': datetime.datetime(1983, 5, 30, 22, 51, 22),
# '来源': 'MRTmgbdlwNlqHiIDUVTN',
# '标题': 929,
# '注册': 'QvYtlygVIopYPasYHCQr',
# '解决': -7138575.3,
# '问题': 1115.0}
fake.pyfloat(left_digits=None, right_digits=None, positive=False, min_value=None, max_value=None) # Python浮点数
# 6.7442382094132
fake.pyint(min_value=0, max_value=9999, step=1) # Python整型值
# 8326
fake.pyiterable(nb_elements=10, variable_nb_elements=True, *value_types) # Python可迭代对象
# {'gang42@gmail.com', Decimal('-638462592926556.0'), 5383, 1608, 185608.962728, datetime.datetime(2013, 8, 7, 10, 44, 51), 'xvqHfWdLyTkaFoguvnqd', datetime.datetime(1999, 9, 10, 4, 41, 29), Decimal('4627589014.65023'), 'http://57.cn/category/', 'UZJwIrsLowvwVGAChwzB', Decimal('68.623476938'), 'mtUbDpTHnQAPVjXzknIM'}
fake.pylist(nb_elements=10, variable_nb_elements=True, *value_types) # Python列表
# [ 589,
# 'https://www.yangbai.cn/main/',
# 'http://fang.cn/faq/',
# 'HvtSTwWqDtughQLYibOd',
# Decimal('-3541501.934427'),
# 2758,
# datetime.datetime(2018, 2, 22, 9, 51, 8),
# 5375,
# 'UVXMfCqJyZwBkfgGhQiH',
# 'HfxybvRTPwaFmuhwvKLT',
# Decimal('-21565647052012.8'),
# 'wEqWsXKTputijSMWhCIb']
fake.pyset(nb_elements=10, variable_nb_elements=True, *value_types) # Python集合
# {7105, 'sidMFYVhXjkNZnHHimJJ', 'yexiuying@kw.cn', 'GPxoyEYixUGAoRCiEmDe', datetime.datetime(2001, 6, 17, 12, 49, 57), 'vOsPAdmmCmkJxeBUpBJP', -75011.0}
fake.pystr(min_chars=None, max_chars=20) # Python字符串
# 'NOlWELuogcxSfRjYauSV'
fake.pystruct(count=10, *value_types) # Python结构
# ( [ 'SQeHWPNdooccsfbZslee',
# 'nDXibfaPXSpmIpxtDUWP',
# 'DrZHepzMfNPRrxgcXwvR',
# 988.956374402,
# 7239,
# 4885,
# datetime.datetime(1972, 6, 13, 14, 18, 11),
# -582284.9732,
# datetime.datetime(1997, 8, 23, 9, 19, 6),
# 'http://www.hu.cn/homepage.php'],
# { '一般': 'oqUQKBhqNylyofEditXs',
# '不要': 'qTlztJembuRZHFEzZnGO',
# '价格': -2100690667.387,
# '国内': datetime.datetime(1989, 9, 3, 11, 27, 11),
# '密码': 'aWaufuJAzfgeuhyXAwDL',
# '开发': 'aJvNisEMynJcAPhbNAHa',
# '方法': 'WVEqHUnnkpUbAnllUqKL',
# '汽车': 'bfQlaULiNfjgkrqQUCnL',
# '用户': 'WDYNlInLyCcIXMFgyLDS',
# '那个': 'qWivpUnOcTwGDhOXihOb'},
# { '个人': { 1: 'http://www.ik.cn/categories/tags/search/homepage/',
# 2: [ 'gBSKOBAYYlPwILaWgory',
# 'xoeueUWWgbvNHDxKYASD',
# 'nkcelmDSpqiQasuKvNZg'],
# 3: { 1: 2000,
# 2: 'SeDZKUpCxrCLlrDIlPxV',
# 3: [Decimal('7833105.737'), Decimal('-7.994')]}},
# '帖子': { 0: 'HXTKojcilYqgYmFUMjuk',
# 1: [6887, 3635, 'http://hezhu.com/list/main/terms.html'],
# 2: { 0: 'hkong@fujiang.cn',
# 1: 4676,
# 2: ['JYEFavcRqcsdpnSMwENU', 'vxu@gmail.com']}},
# '应该': { 7: 'EmzzdZrmUpIetxPktXAU',
# 8: [ Decimal('4786692875733.0'),
# datetime.datetime(2016, 10, 11, 10, 38, 20),
# 'ghtelDQAsBeYDaokgbYg'],
# 9: { 7: 'yanding@yahoo.com',
# 8: 'dtjdazSyZCStWkVYwIvK',
# 9: ['TPTzKNGReDCJmrfTkKmd', 'TKQmVfrNRioICuqCrrDQ']}},
# '我的': { 3: 'http://17.cn/home/',
# 4: [ 'https://www.guiyingsu.cn/category/',
# 'gweRIERFoojbKxRiiliG',
# 'dMjUNjDRCSpdrNAlHXRp'],
# 5: { 3: 'YeIsIoVHcIgAQWYZkQiR',
# 4: 'hGDzyNMVafuDMXSbbhzY',
# 5: [977, 'xCFBFdaPHNyFscSCqEWd']}},
# '或者': { 9: 'owgjdYQvTWZIZRewhkev',
# 10: ['nHusiXLRunAMvynwjJgu', 6500, 'cQRHfcdFJGUyPDlIocqG'],
# 11: { 9: 'sETogfbiwRIqFlrGXeiT',
# 10: 'tliang@kong.cn',
# 11: [ 'https://chaohao.cn/register.html',
# 'fang21@yahoo.com']}},
# '技术': { 4: 8843,
# 5: [-5660697068472.0, 7952, -52210308185.53],
# 6: { 4: 6477,
# 5: 8669,
# 6: ['sGueDRKWFAtTExnruySP', 'YZcIHHkbDRLUgeHhblCu']}},
# '深圳': { 5: 2532,
# 6: [ Decimal('66661967013036.0'),
# 'lei14@yahoo.com',
# 'https://www.fangyao.cn/categories/search.html'],
# 7: { 5: datetime.datetime(1988, 9, 11, 2, 30, 1),
# 6: 50.1,
# 7: [ 'https://www.gang.cn/',
# 'http://www.liao.cn/posts/app/main.html']}},
# '生产': { 2: 2187,
# 3: [ 8629589.339,
# 'QvftOABFsahZurjYIPTr',
# 'GumqSZMuOSIfrUzjTzKO'],
# 4: { 2: 1982,
# 3: 'WatxfisQAelRTuwopoOA',
# 4: ['xiacheng@00.cn', 'flrVEiuWlEnJjbxCazQG']}},
# '起来': { 6: 'luming@yahoo.com',
# 7: [ 'http://www.yu.cn/home.php',
# 'vvmhckwxQGnMCafhjXIA',
# Decimal('-511928454.48')],
# 8: { 6: 'https://www.naguiying.cn/',
# 7: 279.928,
# 8: [5034, 'shaochao@17.cn']}},
# '那么': { 8: 'PNrBODNdjLnhalWpVMXk',
# 9: [ datetime.datetime(1973, 7, 4, 11, 42, 8),
# 'iye@gmail.com',
# 'iEPyTnfNhNhWWXbkStQC'],
# 10: { 8: Decimal('-227034846260.0'),
# 9: Decimal('616424892362.0'),
# 10: [ 'AjpDMNozhUbedUuOZWdL',
# datetime.datetime(1972, 10, 27, 8, 36, 39)]}}})
fake.pytuple(nb_elements=10, variable_nb_elements=True, *value_types) # Python元组
# ( Decimal('989085669.60574'),
# 'yang44@hotmail.com',
# 794,
# datetime.datetime(1989, 12, 11, 4, 10, 40),
# 234,
# 'TyEwXywfUShjlUVwtMAk',
# 'NLUdMSRYoBHmGGPhbwor',
# -69.356824324)
fake.ssn(min_age=18, max_age=90) # 身份证
# '410622198603154708'
fake.android_platform_token() # 安卓
# 'Android 5.0.1'
fake.chrome(version_from=13, version_to=63, build_from=800, build_to=899) # Chrome
# ('Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_10_9) AppleWebKit/534.0 (KHTML, '
# 'like Gecko) Chrome/62.0.826.0 Safari/534.0')
fake.firefox() # FireFox
# ('Mozilla/5.0 (Windows NT 5.1; cs-CZ; rv:1.9.0.20) Gecko/2010-12-02 06:14:30 '
# 'Firefox/3.6.5')
fake.internet_explorer() # Ie
# 'Mozilla/5.0 (compatible; MSIE 7.0; Windows 95; Trident/3.0)'
fake.ios_platform_token() # ios
# 'iPhone; CPU iPhone OS 5_1_1 like Mac OS X'
fake.linux_platform_token() # Linux
# 'X11; Linux i686'
fake.linux_processor() # Linux处理器
# 'x86_64'
fake.mac_platform_token() # Mac
# 'Macintosh; U; PPC Mac OS X 10_11_2'
fake.mac_processor() # Mac处理器
# 'Intel'
fake.opera() # Opera
# 'Opera/8.32.(Windows 98; Win 9x 4.90; mr-IN) Presto/2.9.188 Version/10.00'
fake.safari() # Safari
# ('Mozilla/5.0 (Windows; U; Windows NT 6.0) AppleWebKit/533.43.6 (KHTML, like '
# 'Gecko) Version/4.0.5 Safari/533.43.6')
fake.user_agent() # 随机用户代理
# 'Mozilla/5.0 (compatible; MSIE 9.0; Windows 95; Trident/3.0)'
fake.windows_platform_token() # Windows
# 'Windows NT 6.2'
1import time
2
3btime = time.time()
4a = [x**3 for x in range(10000000)]
5etime = time.time()
6print("used {:.5}s" % (etime-btime))
1data = (i**2 for i in range(100000))
2dlst = list(data)
3dset = set(data)
4
51234 in dlst
61234 in dset
python atexit 模块定义了一个 register 函数,用于在 python 解释器中注册一个退出函数, 这个函数在解释器正常终止时自动执行,一般用来做一些资源清理的操作。 atexit 按注册的相反顺序执行这些函数; 例如注册A、B、C,在解释器终止时按顺序C,B,A运行。
1import atexit
2
3print("some code ............")
4
5
6def exit0(*args, **kwarg):
7 print('exit0')
8 for arg in args:
9 print(' ' * 4, arg)
10
11 for item in kwarg.items():
12 print(' ' * 4, item)
13
14
15def exit1():
16 print('exit1')
17 raise Exception('exit1')
18
19
20def exit2():
21 print('exit2')
22 print(1 / 0)
23
24
25atexit.register(exit0, *[1, 2, 3], **{"a": 1, "b": 2, })
26atexit.register(exit1)
27atexit.register(exit2)
28
29
30@atexit.register
31def exit3():
32 print('exit3')
33
34
35print('other code ..............')
36
37
38if __name__ == '__main__':
39 pass
openpyxl是用于读取/写入Excel 2010 xlsx/xlsm文件的Python库, 也就是说openpyxl这个Python库不支持xls文件的读取和操作
可以手工打开另存转换格式 或者
1import os
2import win32com.client as win32
3filename = '.\1.xls'
4Excelapp = win32.gencache.EnsureDispatch('Excel.Application')
5workbook = Excelapp.Workbooks.Open(filename)
6# 转xlsx时: FileFormat=51,
7# 转xls时: FileFormat=56,
8workbook.SaveAs(filename.replace('xls', 'xlsx'), FileFormat=51)
9workbook.Close()
10Excelapp.Application.Quit()
11# 删除源文件
12# os.remove(filename)
13
14# 如果想将xlsx的文件转换为xls的话,则可以使用以下的代码:
15# workbook.SaveAs(filename.replace('xlsx', 'xls'), FileFormat=56)
1import openpyxl
2
3# 创建新工作簿
4wb = openpyxl.WorkBook()
5# 在指定位置新建工作表
6ws = wb.create_sheet('sheetname', 0)
7
8# 打开已有工作簿
9wb = openpyxl.load_workbook('xlsx_filename')
10# 打开已有工作表
11ws = wb['sheetname']
12ws1 = wb.get_sheet_by_name('sheetname')
13
14# 设置工作表标签颜色
15ws.sheet_properties.tabColor = 'ff0000'
16
17# 读取已有所有工作表名称
18for sht in ws.sheetnames:
19 print("sht : ", sht)
20# 保存并退出
21wb.save('xlsx_filename')
22wb.close()
1# 访问指定单元格
2cell_1 = ws['A1']
3cell_2 = ws.cell(row=1, column=1)
4
5# 返回指定单元格的值
6value_1 = ws['A1'].value
7value_2 = ws.cell(row=1, column=1).value
8
9# 设置指定单元格内容
10ws['A1'].value = 'xlsx 内容'
11ws.cell(row=1, column=1).value ='xlsx 内容'
12
13# 多个单元格
14# 访问A1至C3范围单元格
15cell_range = ws['A1':'C3']
16# 访问A列所有存在数据的单元格
17colA = ws['A']
18# 访问A列到C列所有存在数据的单元格
19col_range = ws['A:C']
20# 访问第1行所有存在数据的单元格
21row1 = ws[1]
22# 访问第1行至第5行所有存在数据的单元格
23row_range = ws[1:5]
24
25# 多行列
26for row in ws.iter_rows(min_row=1, max_col=2, max_row=2):
27 for cell in row:
28 print(cell)
29#输出:
30<Cell 'sht'.A1>
31<Cell 'sht'.B1>
32<Cell 'sht'.A2>
33<Cell 'sht'.B2>
34
35for col in ws.iter_cols(min_row=1, max_col=2, max_row=2):
36 for cell in col:
37 print(cell)
38#输出:
39<Cell 'sht'.A1>
40<Cell 'sht'.A2>
41<Cell 'sht'.B1>
42<Cell 'sht'.B2>
43
44# 单元格的常见属性
45print(ws.cell(column=2, row=9).column_letter)
46print(ws.cell(column=2, row=9).coordinate)
47print(ws.cell(column=2, row=9).col_idx)
48print(ws.cell(column=2, row=9).encoding)
49print(ws.cell(column=2, row=9).offset)
50print(ws.cell(column=2, row=9).is_date)
51print(ws.cell(column=2, row=9).data_type)
52print(ws.cell(column=2, row=9).has_style)
53print(ws.cell(column=2, row=9).style)
54print(ws.cell(column=2, row=9).style_id)
55print(ws.cell(column=2, row=9).font)
56print(ws.cell(column=2, row=9).alignment)
57print(ws.cell(column=2, row=9).border)
58print(ws.cell(column=2, row=9).fill)
59print(ws.cell(column=2, row=9).number_format)
60print(ws.cell(column=2, row=9).hyperlink)
61
62# 调整列宽和行高
63# 调整列宽
64ws.column_dimensions['A'].width = 20.0
65# 调整行高
66ws.row_dimensions[1].height = 40
67
68# 合并单元格
69ws.merge_cells("A1:B1")
70ws.merge_cells(start_column=3,end_column=5,start_row=3,end_row=5)
1from openpyxl import *
2from openpyxl.styles import PatternFill, Font, Alignment, Border, Side
3
4# 设置字体
5font = Font(name='微软雅黑',
6 size=11,
7 color='FF000000',
8 bold=True,
9 italic=True,
10 vertAlign='baseline',
11 underline='double',
12 strike=False)
13wsheet['A2'].font = font
14
15# 边线设置
16side_type = Side(border_style='mediumDashDot',color='FF000000')
17border = Border(left=side_type,
18 right=side_type,
19 top=side_type,
20 bottom=side_type,
21 diagonal=side_type,
22 diagonal_direction=30,
23 outline=side_type,
24 vertical=side_type,
25 horizontal=side_type
26 )
27
28wsheet['A3'].border = border
29# border_style的样式有:
30# ‘dashDot’,‘dashDotDot’,‘dashed’,‘dotted’,‘double’,
31# ‘hair’,‘medium’,‘mediumDashDot’,‘mediumDashDotDot’,
32# ‘mediumDashed’,‘slantDashDot’,‘thick’,‘thin’
33
34# 填充设置
35fill = PatternFill(fill_type = 'darkDown',start_color='A6DA70D6',end_color='000000')
36wsheet['A4'].fill = fill
37# fill_type类型有:'none'、'solid'、'darkDown'、'darkGray'、'darkGrid'、'darkHorizontal'、'darkTrellis'、'darkUp'、'darkVertical'、'gray0625'、
38# 'gray125'、'lightDown'、'lightGray'、'lightGrid'、'lightHorizontal'、
39# 'lightTrellis'、'lightUp'、'lightVertical'、'mediumGray'
40
41# 对齐设置
42align = Alignment(horizontal='center',vertical='center',text_rotation=0,wrap_text=True,shrink_to_fit=True,indent=0)
43wsheet['A6'].alignment = align
44# Horizontal:水平方向,左对齐left,居中center对齐和右对齐right可选。
45# Vertical:垂直方向,有居中center,靠上top,靠下bottom,两端对齐justify等可选。
46# text_rotation:文本旋转度。
47# wrap_text:自动换行
48# Indent:缩进。
49
50# 数字格式设置
51wsheet['A9'].number_format = 'd-mmm-yy'
52
53col = ws.column_dimensions['A']
54col.number_format = u'#,##0.00€'
55# 一些格式
56# 0: 'General',
57# 1: '0',
58# 2: '0.00',
59# 3: '#,##0',
60# 4: '#,##0.00',
61# 5: '"$"#,##0_);("$"#,##0)',
62# 6: '"$"#,##0_);[Red]("$"#,##0)',
63# 7: '"$"#,##0.00_);("$"#,##0.00)',
64# 8: '"$"#,##0.00_);[Red]("$"#,##0.00)',
65# 9: '0%',
66# 10: '0.00%',
67# 11: '0.00E+00',
68# 12: '# ?/?',
69# 13: '# ??/??',
70# 14: 'mm-dd-yy',
71# 15: 'd-mmm-yy',
72# 16: 'd-mmm',
73# 17: 'mmm-yy',
74# 18: 'h:mm AM/PM',
75# 19: 'h:mm:ss AM/PM',
76# 20: 'h:mm',
77# 21: 'h:mm:ss',
78# 22: 'm/d/yy h:mm',
79#
80# 37: '#,##0_);(#,##0)',
81# 38: '#,##0_);[Red](#,##0)',
82# 39: '#,##0.00_);(#,##0.00)',
83# 40: '#,##0.00_);[Red](#,##0.00)',
84#
85# 41: r'_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)',
86# 42: r'_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_)',
87# 43: r'_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)',
88#
89# 44: r'_("$"* #,##0.00_)_("$"* \(#,##0.00\)_("$"* "-"??_)_(@_)',
90# 45: 'mm:ss',
91# 46: '[h]:mm:ss',
92# 47: 'mmss.0',
93# 48: '##0.0E+0',
94# 49: '@',
1# 所有可用公式都在这里
2from openpyxl.utils import FORMULAE
3print(len(FORMULAE))
4print(FORMULAE)
5
6
7sheet["C2"] = "=SUM(A2,B2)"
1ws.merge_cells('A2:D2')
2ws.unmerge_cells('A2:D2')
3# or equivalently
4ws.merge_cells(start_row=2, start_column=1, end_row=4, end_column=4)
5ws.unmerge_cells(start_row=2, start_column=1, end_row=4, end_column=4)
1ws.column_dimensions.group('A','D', hidden=True)
2ws.row_dimensions.group(1,10, hidden=True)
3wb.save('group.xlsx')
1ws.insert_rows(7)
2ws.insert_cols(3)
3ws.delete_rows(7)
4ws.delete_cols(3)
1import xlwings as xw
2
3# 创建一个新的App,并在新App中新建一个Book
4wb = xw.Book()
5wb.save('1.xlsx')
6wb.close()
7
8# 当前App下新建一个Book
9# visible参数控制创建文件时可见的属性
10app=xw.App(visible=False,add_book=False)
11wb=app.books.add()
12
13ws = wb.sheets.avtive
14ws1 = wb.sheets.add('新建工作表', after=ws)
15
16wb.save('1.xlsx')
17wb.close()
18#结束进程
19app.quit()
1import xlwings as xw
2app=xw.App(visible=True,add_book=False)
3#不显示Excel消息框
4app.display_alerts=False
5#关闭屏幕更新,可加快宏的执行速度
6app.screen_updating=False
7
8wb=app.books.open('1.xlsx')
9# 输出打开的excle的绝对路径
10# print(wb.fullname)
11wb.save()
12wb.close()
13# 退出excel程序,
14app.quit()
15# 通过杀掉进程强制Excel app退出
16# app.kill()
17#
18# 以第一种方式创建Book时,打开文件的操作可如下
19wb = xw.Book('1.xlsx')
20
21app = xw.App(visible=False, add_book=False)
22app.display_alerts = False # 关闭一些提示信息,可以加快运行速度。 默认为 True。
23app.screen_updating = False # 更新显示工作表的内容。默认为 True。关闭它也可以提升运行速度。
24
25wb = app.books.open("./111.xlsx")
26ws = wb.sheets['ExportOrderList11954161104']
1# 在A1单元格写入值
2# 实例化一个工作表对象
3sheet1 = wb.sheets["sheet1"]
4# 或者
5# sheet1 =xw.books['1.xlsx'].sheets['sheet1']
6输出工作簿名称
7# print(sheet1.name)
8# 写入值
9sheet1.range('A1').value = 'python知识学堂'
10# 读值并打印
11print('value of A1:',sheet1.range('A1').value)
12# 清空单元格内容,如果A1中是图片,此方法没有效果
13sheet1.range('A1').clear()
14# 传入列表写入多行值
15sheet1.range('A1').value = [['a','b','c'],[1,2,3]]
16
17# 当然也可以将pandas的DataFrame数据写入
18import pandas as pd
19df = pd.DataFrame([[1,2], [3,4]], columns=['A', 'B'])
20sheet1.range('A1').value = df
21# 读取数据,输出类型为DataFrame
22sheet1.range('A1').options(pd.DataFrame, expand='table').value
1# 读取全部行列
2max_row, max_col = sht.used_range.last_cell.row, sht.used_range.last_cell.column
3lst = sht.range((1,1), (max_row, max_col)).value
4
5rng = sht.range('A1:D3')
6for cell in rng:
7 print(cell.value)
8
9# 读取行, 列(0起始)
10rng = sht[2:5, :3]
11for cell in rng:
12 print(cell.value)
1"""设置单元格大小"""
2ws.autofit() #在整个工作表上自动调整宽度,可传参数
3ws.autofit(axis='c') # 在整个工作表上自动调整列的宽度
4ws.autofit(axis='r') # 在整个工作表上自动调整行的宽度
5ws.autofit('c') # 在整个工作表上自动调整列的宽度
6ws.autofit('r') # 在整个工作表上自动调整行的宽度
7ws.range(1,4).column_width = 5 # 设置第4列 列宽。(1,4)为第1行第4列的单元格
8ws.range(1,4).row_height = 20 # 设置第1行 行高
1b3 = ws.range('b3')
2
3# Borders(9) 底部边框,LineStyle = 1 直线。
4b3.api.Borders(9).LineStyle = 1
5b3.api.Borders(9).Weight = 3 # 设置边框粗细。
6
7# Borders(7) 左边框,LineStyle = 2 虚线。
8b3.api.Borders(7).LineStyle = 2
9b3.api.Borders(7).Weight = 3
10
11# Borders(8) 顶部框,LineStyle = 5 双点划线。
12b3.api.Borders(8).LineStyle = 5
13b3.api.Borders(8).Weight = 3
14
15# Borders(10) 右边框,LineStyle = 4 点划线。
16b3.api.Borders(10).LineStyle = 4
17b3.api.Borders(10).Weight = 3
18
19# Borders(5) 单元格内从左上角 到 右下角。
20b3.api.Borders(5).LineStyle = 1
21b3.api.Borders(5).Weight = 3
22
23# Borders(6) 单元格内从左下角 到 右上角。
24b3.api.Borders(6).LineStyle = 1
25b3.api.Borders(6).Weight = 3
26
27"""如果是一个区域的单元格,内部边框设置如下"""
28# Borders(11) 内部垂直边线。
29b3.api.Borders(11).LineStyle = 1
30b3.api.Borders(11).Weight = 3
31
32# Borders(12) 内部水平边线。
33b3.api.Borders(12).LineStyle = 1
34b3.api.Borders(12).Weight = 3
1# 使用公式
2ws.range('AB2').formula='=SUM(A1,A2)'
1# coding=utf-8
2import xlwings as xw
3# 设置程序不可见运行
4app = xw.App(visible=False, add_book=False)
5
6# =============== 第一部分,创建并写入数据 =====================
7# 创建一个test2.xlsx表,并写入数据
8# wb = app.books.add()
9# ws = wb.sheets.active
10# arr = []
11# for col in range(1,4):
12# arr_temp = []
13# for row in range(1,4):
14# arr_temp.append(col*10+row)
15# arr.append(arr_temp)
16# ws.range('A1:B3').value=arr
17# wb.save('data/test2.xlsx')
18# wb.close()
19# app.quit()
20# exit()
21
22# ============== 第二部分,插入、删除行和列 ========================
23
24# 导入已存的demo表格
25load_wb = app.books.open('data/test2.xlsx')
26# # 打开活动的工作薄的活动工作簿,或者指定的工作簿
27load_ws = load_wb.sheets.active
28# load_ws = load_wb.sheets['Sheet']
29
30# 获取总行数(存在数据)
31rows = load_ws.api.UsedRange.Rows.count
32cols = load_ws.api.UsedRange.Columns.count
33# print('该表格总共有:'+str(rows)+' 行')
34# print('该表格总共有:'+str(cols)+' 列')
35# exit()
36
37
38# 1-①在第二行前插入2行(可理解为: 在第2-4行插入空白行)
39# load_ws.api.rows('2:4').insert
40# 1-②删除第2-4行
41# load_ws.api.rows('2:4').delete
42# 2-①在第二列前插入2列(这里处理的不是很好,其实是增加了对应区域的单元格,并未直接增加列)
43# load_ws.range('B1:C'+str(cols)).api.insert
44# 2-②删除第2-4列
45# load_ws.range('B1:C'+str(cols)).api.delete
46
47# ============== 第三部分,修改指定单元格的值 ========================
48# load_ws.range('A1').value = 'x11'
49
50# ============== 第四部分,合并单元格 ========================
51# load_ws.range('A1:A2').api.merge
52
53# ============== 第五部分,获取单元格横纵坐标index ========================
54rng=xw.Range('B2')
55# 返回当前格子的行值
56# print(rng.row)
57# 返回当前格子的列值
58# print(rng.column)
59# 返回和设置当前格子的高度和宽度
60print(rng.width)
61print(rng.height)
62rng.row_height=40
63rng.column_width=50
64# 指定单元格的高度和宽度自适应
65# rng.columns.autofit()
66rng.rows.autofit()
67print(rng.width)
68print(rng.height)
69# load_ws.range('A1:A2').api.height = 20
70
71
72# ============== 第六部分,其它 ========================
73# lst=load_ws.range('A1:A'+str(load_ws['A1048576'].end('up').row)).value #把excel单列值读取到列表中
74# lst1=load_ws.range('A1:C'+str(load_ws['A1048576'].end('up').row)).value # 把excel连续两个列的值读取到列表中
75# lst=load_ws.range('A1:A'+str(load_ws['A1048576'].end('up').row)).value #A列的值
76# lst2=load_ws.range('C1:C'+str(load_ws['A1048576'].end('up').row)).value#C列的值
77# lst3=list(zip(lst,lst2))#合并起来然后转为列表
78# dicta=dict(lst3)#列表转为字典
79
80# ============== 第七部分,Office操作文档 ========================
81# https://docs.microsoft.com/en-us/office/vba/api/excel.range(object)
82
83
84
85load_wb.save()
86load_wb.close()
87app.quit()
待续……
函数接收一个 函数名 作为参数 内部定义一个函数, 接收参数, 然后 内部函数内部 执行接收的函数名 最后外部函数返回内部函数
def loger(fun):
def show(*args, **kwargs):
print("记录日志->执行前")
fun(*args, **kwargs)
print("记录日志->执行后")
return show
@loger
def xiaoming():
print("function is running......")
@loger
def jack():
print("function is running......")
xiaoming()
jack()
print("---" * 30)
在不接受参数的装饰器基础上, 外面增加一层函数, 接收参数
def say_hello(contry):
def loger(fun):
def show(*args, **kwargs):
if contry == 'china':
print('中国')
elif contry == 'english':
print('English')
print("记录日志->执行前")
fun(*args, **kwargs)
print("记录日志->执行后")
return show
return loger
@say_hello('china')
def xiaoming():
print("function is running......")
@say_hello('english')
def jack():
print("function is running......")
xiaoming()
jack()
print("---" * 30)
init 接收被装饰的函数名 call 接收参数
class Loger(object):
def __init__(self, fun):
self.fun = fun
def __call__(self, *args, **kwargs):
print("before fun run")
self.fun(*args, **kwargs)
print("after fun run")
@Loger
def xiaoming():
print("function is running......")
@Loger
def jack():
print("function is running......")
xiaoming()
jack()
print("---" * 30)
init 接收参数 call 接收被装饰的函数名, 内部定义一个函数接收参数, 并执行外部接收的函数名
class SLoger(object):
def __init__(self, contry):
self.contry = contry
def __call__(self, fun):
def show(*args, **kwargs):
if self.contry == 'china':
print("中国")
elif self.contry == 'english':
print("English")
print("before fun run")
fun(*args, **kwargs)
print("after fun run")
return show
@SLoger('china')
def xiaoming():
print("function is running......")
@SLoger('english')
def jack():
print("function is running......")
xiaoming()
jack()
print("---" * 30)
1pip install ipython jupyter
2pip install jupyterlab
jupyter notebook --generate-config
Writing default config to: /root/.jupyter/jupyter_notebook_config.py
jupyter lab --generate-config
1# ipython
2In [1]: from notebook.auth import passwd
3In [2]: passwd()
4Enter password:
5Out[2]: 'argon2:$argon2id$v=19$m=10240,t=10,p=8$Sunk/A1dg/SA'
c.NotebookApp.ip = '*' # 对外提供访问的ip
c.NotebookApp.port = 8888 # 对外提供访问的端口
c.NotebookApp.open_browser = False # 启动不打开浏览器
c.NotebookApp.password = 'sha1:f8b5f5dbeca8:d1f5b93d5e787e4bf1bf4ad2c48c177ba79f55dd' # 上面生成的秘钥
c.NotebookApp.notebook_dir = '/root/jupyter_dir' # 设置jupyter启动后默认文件夹
c.NotebookApp.allow_root = True # 允许root用户执行
pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
pip install jupyter_nbextensions_configurator
jupyter nbextensions_configurator enable --user
pip install jupyterthemes
jt -l # 列出可选的主题
# -f(字体) -fs(字体大小) -cellw(占屏比或宽度) -ofs(输出段的字号) -T(显示工具栏) -N(显示自己主机名)
jt -t monokai -f fira -fs 9 -ofs 9 -dfs 9 -T -N
nohup jupyter notebook &>./jupyter.log &
nohup jupyter lab --allow-root &>./jupyter.log &
rejn(){
pid=$(ps aux | grep jupyter-notebook | grep -v 'grep' | awk '{print $2}')
kill -9 ${pid}
nohup jupyter notebook &>./jupyter.log &
}
rejl(){
pid=$(ps aux | grep jupyter-lab | grep -v 'grep' | awk '{print $2}')
kill -9 ${pid}
nohup jupyter lab --allow-root &>./jupyterlab.log &
}
pip install arrow
import arrow
now = arrow.now()
print(now)
print(now.year, now.month, now.day, now.hour, now.minute, now.second, now.microsecond)
print(now.tzinfo, now.fold, now.timestamp)
print('-'*12)
print(now.format())
print(now.format('YYYY-MM-DD HH:mm:ss'))
print('-'*12)
utcnow = arrow.utcnow()
print(utcnow)
print('-'*12)
t = arrow.get("2020-10-11 12:34:45", "YYYY-MM-DD HH:mm:ss")
print(t)
print('-'*12)
t = arrow.get(1604555923)
print(t)
print('-'*12)
t = arrow.get(2020, 12, 23, 9, 10, 11)
print(t)
print('-'*12)
t = arrow.now()
print(t)
print(t.replace(year=2011, hour=11))
t = arrow.now()
print(t)
print(t.shift(days=1))
print(t.shift(days=-1))
print('-'*12)
print(arrow.now().span('hours'))
print(arrow.now().span('days'))
print(arrow.now().floor("days"))
print(arrow.now().ceil("days"))
print('-'*12)
b = arrow.now().shift(days=-2).datetime
e = arrow.now().shift(days=+2).datetime
for item in arrow.now().range('days', b, e):
print(item, item.format('YYYY-MM-DD HH:mm:ss'))
关于docsy主题模板
docsy主题非常适合用于开源项目,支持文档和博客。
Docsy是一个文件式的网站,提供了使用者一些样板以及文件指南,能良好的支持技术文件发布。
Docsy是由Hugo等开源工具打造而成,结合Google的开源文件创建经验,提供方便的工具,帮助使用者快速建立开源项目文件网站。
1# 配置hugo extend 环境
2wget https://github.com/gohugoio/hugo/releases/download/v0.117.0/hugo_extended_0.117.0_linux-amd64.tar.gz
3tar -zxvf hugo_extended_0.117.0_linux-amd64.tar.gz
4cd hugo_extended_0.117.0_linux-amd64
5cp hugo /usr/bin/hugo
6
7
8wget https://nodejs.org/dist/v20.5.1/node-v20.5.1-linux-x64.tar.xz
9tar xvf node-v20.5.1-linux-x64.tar.xz
10cd node-v20.5.1-linux-x64
11# 配置node环境
12echo "PATH='path-to-node-v20.5.1-linux-x64/bin:$PATH'" >> ~/.bash_profile
1git clone --depth 1 https://github.com/google/docsy-example.git website
2cd website
3npm install postcss postcss-cli autoprefixer
Chrome浏览器中会自动转换网址从http到https,启用安全访问
但是, 有时候我们不需要它强制转换, 如: 证书失效…..
此时在chrome地址栏输入 chrome://net-internals/#hsts
打开的页面中 左侧选择 Domain Security Policy 然后右侧找到 Query HSTS/PKP domain
在下面的输入框中输入要访问的域名, 可以查询是否该域名是否会自动转换http->https
想要取消自动转换, 则同页面最底部找到Delete domain security policies
在其下的文本框中输入 不想转换http->https的域名提交
这样再次访问该域名时, 就不会自动添加https了
从Redis 2.8.0 开始 键空间通知允许客户端订阅发布/订阅信道来接收以某种方式影响Redis数据集的事件
由于Redis的发布/订阅当前是发后即忘模式的,因此如果你的应用需要可靠的事件通知,则无法满足,也就是说,
如果你的发布/订阅客户端断开连接并在稍后重连,客户端断开的这段时间内的所有事件通知都会丢失。
键空间通知被实现成对每个影响Redis数据集的操作发送两个不同类型的事件。例如,一个在0号数据库中对名称为mykey的键执行DEL操作将触发推送两条消息,
相当于执行了下面两条PUBLISH命令:
PUBLISH keyspace@0:mykey del
PUBLISH keyevent@0:del mykey
很容易看出一个信道可以监听所有针对键mykey的事件,另一个信道允许获取对所有键执行删除操作的信息。
第一类事件,以keyspace为前缀的信道被称为键-空间通知,
第二类事件,以keyevent为前缀的信道被称为键-事件通知。
默认情况下,键空间事件通知是被禁用的,因为这个功能会消耗一些CPU,默认打开是不明智的。可以在redis.conf文件中使用notify-keyspace-events或CONFIG SET命令启用它。
参数:
K 键空间事件,以__keyspace@
__为前缀发布消息
E 键事件事件,以__keyevent@__为前缀发布消息
g 通用命令(非特定类型),例如 DEL、 EXPIRE、 RENAME等
$ 字符串命令
l 列表命令
s 集合命令
h 哈希命令
z 有序集合命令
x 键过期事件(每次当一个键过期时生成的事件)
e 键淘汰事件(当一个键由于内存超量导致被淘汰时生成的事件)
A 参数g$lshzxe的别名,因此"AKE"字符串表示所有的事件
K或E至少有一个应该出现在参数字符串中,否则,无论字符串的其他部分是什么,都不会推送事件。 例如,为了只针对列表开启键-空间事件,配置参数必须设置为Kl,以此类推。 字符串KEA可以用来开启任何可能的事件。
DEL 命令会对每一个被删除的键生成一个del event。
RENAME 命令会生成两个事件,对源键生成一个rename_from事件,对目标键生成一个rename_to事件。
EXPIRE 命令在对一个键设置过期时间时生成一个expire event,或在每次使用正数时间对一个键设置过期时间后导致键因过期被删除时生成一个expired event(查看EXPIRE的文档来获取更多信息)。
SORT 命令在使用STORE设置一个新建时会生成一个sortstore event。如果结果列表为空,并使用了STORE选项,且相同的键名已经存在,结果就是这个键被删除,因此这种情况下会生成一个del event。
SET和它的左右变种(SETEX、SETNX、GETSET)会生成set events。然而SETEX同时还会生成一个expire events。
MSET 会对每个键生成一个独立的set event。
SETRANGE 命令生成一个setrange event。
INCR、DECR、INCRBY、DECRBY 命令都会生成incrby events。
INCRBYFLOAT 命令会生成一个incrbyfloat events。
APPEND 命令会生成一个append event。
LPUSH和LPUSHX 命令会生成一个单一的lpush event,即使是在复杂情况下。
RPUSH和RPUSHX 命令会生成一个单一的rpush event,即使是在复杂情况下。
RPOP 命令会生成一个rpop event。如果列表中的最后一个元素被弹出,还会额外生成一个del event。
LPOP 命令会生成一个lpop event。如果列表中的第一个元素被弹出,还会额外生成一个del event。
LINSERT 命令会生成一个linsert event。
LSET 命令会生成一个lset event。
LREM 命令会生成一个lrem event,如果结果列表为空且键被删除将额外生成一个del event。
LTRIM 命令会生成一个ltrim event,如果结果列表为空且键被删除将额外生成一个del event。
RPOPLPUSH和BRPOPLPUSH 命令会生成一个rpop event和一个lpush event。在这两种情况下,顺序都是有保证的(lpush event将总是在rpop event之后被推送)。如果结果列表长度为0且键被删除将额外生成一个del event。
HSET、HSETNX和HMSET 都会生成一个单一的hset event。
HINCRBY 命令会生成一个hincrby event。
HINCRBYFLOAT 命令会生成一个hincrbyfloat event。
HDEL 命令会生成一个单一的hdel event,如果结果哈希为空且键被删除将额外生成一个del event。
SADD 命令会生成一个单一的sadd event,即使是在复杂情况下。
SREM 命令会生成一个单一的srem event,如果结果集合为空且键被删除将额外生成一个del event。
SMOVE 命令会对源键生成一个srem event,且对目标键生成一个sadd event。
SPOP 命令会生成一个spop event,如果结果集合为空且键被删除将额外生成一个del event。
SINTERSTORE、SUNIONSTORE、SDIFFSTORE 会分别生成sinterstore event、sunionostore event、sdiffstore event。在集合为空且被存储的键已经存在的特殊情况下,由于key会被删除会生成一个del event。
ZINCR 命令会生成一个zincr event。
ZADD 命令会生成一个单一的zadd event,即使有多个元素一次性被添加。
ZREM 命令会生成一个的那一的zrem event,即使有多个元素一次性被删除。当结果有序集合为空且键被删除,会生成一个额外的del event。
ZREMBYSCORE 命令会生成一个单一的zrembyscore event。当结果有序集合为空且键被删除,会生成一个额外的del event。
ZREMBYRANK 命令会生成一个单一的zrembyrank event。当结果有序集合为空且键被删除,会生成一个额外的del event。
ZINTERSTORE和ZUNIONSTORE 会分别生成zinterstore event和zunionstore event。在有序集合为空且被存储的键已经存在的特殊情况下,由于key会被删除会生成一个del event。
每次由于键的过期时间到导致键被从数据集中删除时,会生成一个expired event。
每次由于Redis超过最大内存限制 ,使用maxmemory policy释放内存导致一个键从数据集中被淘汰时,会生成一个evicted event。
** 只有在目标键真正被修改时,所有命令才会生成事件。例如一个SREM命令从一个集合中删除了一个不存在的元素,这实际上不会对键造成改变,因此不会生成任何事件。 **
测试用例:
redis-cli config set notify-keyspace-events KA
redis-cli psubscribe '__keyspace*'
有生存时间的键在Redis中过期有两种方式:
当键被一个命令访问且发现键已过期。
通过在后台系统中运行定时任务增量地查找过期键,这样能够收集到那些从未被访问键。
当一个键被访问且被上述两种方法之一发现已过期时会生成expired events,这就会导致一个结果,Redis服务器将无法保证在键的生存时间变为0时立即生成expired events。
如果没有命令不断地访问键,且有很多的键被设置了生存时间,则在键的生存时间下降到0和生成expired events这之间会有一个显著的延迟。
基本上来说,Redis服务器是在删除过期键时,而不是在键的生存时间理论上变为0时生成expired events。