一文教会你如何使用 iLogtail SPL 处理日志
off999 2025-01-21 20:37 18 浏览 0 评论
随着流式处理的发展,出现了越来越多的工具和语言,使得数据处理变得更加高效、灵活和易用。在此背景下,SLS 推出了 SPL(SLS Processing Language) 语法,以此统一查询、端上处理、数据加工等的语法,保证了数据处理的灵活性。iLogtail 作为日志、时序数据采集器,在 2.0 版本中,全面支持了 SPL 。本文对处理插件进行了梳理,介绍了如何编写 SPL 语句,从插件处理模式迁移到 2.0 版本的 SPL 处理模式,帮助用户实现更加灵活的端上数据处理。
SPL
Cloud Native
iLogtail 一共支持 3 种处理模式。
- 原生插件模式:由 C++ 实现的原生插件,性能最强。
- 拓展插件模式:由 Go 实现的拓展插件,提供了丰富的生态,足够灵活。
- SPL 模式:随着 iLogtail 2.0 在 C++ 处理插件中支持了 SPL 的处理能力,对数据处理能力带来了很大的提升,兼顾性能与灵活性。用户只需要编写 SPL 语句,即可以利用 SPL 的计算能力,完成对数据的处理。SPL 语法可以参考:https://help.aliyun.com/zh/sls/user-guide/spl-syntax/
特点 | 开发门槛 | |
原生插件 |
|
|
扩展插件 |
|
|
SPL |
|
|
总的来说,iLogtail 2.0 + SPL 主要有以下的优势:
- 统一数据处理语言:对于同样一种格式的数据,用户可以在不同场景中使用同一种语言进行处理,提高了数据处理的效率
- 查询处理更高效:SPL 对弱结构化数据友好,同时 SPL 主要算子由 C++ 实现,接近 iLogtail 1.X 版本的原生性能
- 丰富的工具和函数:SPL 提供了丰富的内置函数和算子,用户可以更加灵活地进行组合
- 简单易学:SPL 属于一种低代码语言,用户可以快速上手,日志搜索、处理一气呵成
接下来,本文将介绍如何用灵活的 SPL 语句,实现其他两种处理模式相同的处理能力。
原生插件对比
Cloud Native
正则解析
根据正则提取提取字段。输入 Nginx 格式:
127.0.0.1 - - [07/Jul/2022:10:43:30 +0800] "POST /PutData?Category=YunOsAccountOpLog" 0.024 18204 200 37 "-" "aliyun-sdk-java"
原有插件:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtal/debug/simple.log
processors:
- Type: processor_parse_regex_native
SourceKey: content
Regex: ([\d\.]+) \S+ \S+ \[(\S+) \S+\] \"(\w+) ([^\\"]*)\" ([\d\.]+) (\d+) (\d+) (\d+|-) \"([^\\"]*)\" \"([^\\"]*)\"
Keys:
- ip
- time
- method
- url
- request_time
- request_length
- status
- length
- ref_url
- browser
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| parse-regexp content, '([\d\.]+) \S+ \S+ \[(\S+) \S+\] \"(\w+) ([^\\"]*)\" ([\d\.]+) (\d+) (\d+) (\d+|-) \"([^\\"]*)\" \"([^\\"]*)\"' as ip, time, method, url, request_time, request_length, status, length, ref_url, browser
| project-away content
flushers:
- Type: flusher_stdout
OnlyStdout: true
输出:{
"ip": "127.0.0.1",
"time": "07/Jul/2022:10:43:30",
"method": "POST",
"url": "/PutData?Category=YunOsAccountOpLog",
"request_time": "0.024",
"request_length": "18204",
"status": "200",
"length": "37",
"ref_url": "-",
"browser": "aliyun-sdk-java",
"__time__": "1713184059"
}
分隔符解析
根据分隔符分隔提取字段,输入:
127.0.0.1,07/Jul/2022:10:43:30 +0800,POST,PutData Category=YunOsAccountOpLog,0.024,18204,200,37,-,aliyun-sdk-java
原有插件:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_parse_delimiter_native
SourceKey: content
Separator: ","
Quote: '"'
Keys:
- ip
- time
- method
- url
- request_time
- request_length
- status
- length
- ref_url
- browser
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| parse-csv content as ip, time, method, url, request_time, request_length, status, length, ref_url, browser
| project-away content
flushers:
- Type: flusher_stdout
OnlyStdout: true
输出:{
"ip": "127.0.0.1",
"time": "07/Jul/2022:10:43:30 +0800",
"method": "POST",
"url": "PutData?Category=YunOsAccountOpLog",
"request_time": "0.024",
"request_length": "18204",
"status": "200",
"length": "37",
"ref_url": "-",
"browser": "aliyun-sdk-java",
"__time__": "1713231487"
}
Json 解析
解析 json 格式日志,输入:
{"url": "POST /PutData?Category=YunOsAccountOpLog HTTP/1.1","ip": "10.200.98.220",
"user-agent": "aliyun-sdk-java",
"request": "{\"status\":\"200\",\"latency\":\"18204\"}",
"time": "07/Jul/2022:10:30:28",
"__time__": "1713237315"
}
原有插件:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_parse_json_native
SourceKey: content
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| parse-json content
| project-away content
flushers:
- Type: flusher_stdout
OnlyStdout: true
输出:{ "url": "POST /PutData?Category=YunOsAccountOpLog HTTP/1.1",
"ip": "10.200.98.220",
"user-agent": "aliyun-sdk-java",
"request": "{\"status\":\"200\",\"latency\":\"18204\"}",
"time": "07/Jul/2022:10:30:28",
"__time__": "1713237315"
}
正则解析+时间解析
根据正则表达式解析字段,并将其中的一个字段解析成日志时间,输入:
127.0.0.1,07/Jul/2022:10:43:30 +0800,POST,PutData Category=YunOsAccountOpLog,0.024,18204,200,37,-,aliyun-sdk-java
原有插件:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_parse_regex_native
SourceKey: content
Regex: ([\d\.]+) \S+ \S+ \[(\S+) \S+\] \"(\w+) ([^\\"]*)\" ([\d\.]+) (\d+) (\d+) (\d+|-) \"([^\\"]*)\" \"([^\\"]*)\"
Keys:
- ip
- time
- method
- url
- request_time
- request_length
- status
- length
- ref_url
- browser
- Type: processor_parse_timestamp_native
SourceKey: time
SourceFormat: '%Y-%m-%dT%H:%M:%S'
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| parse-regexp content, '([\d\.]+) \S+ \S+ \[(\S+)\] \"(\w+) ([^\\"]*)\" ([\d\.]+) (\d+) (\d+) (\d+|-) \"([^\\"]*)\" \"([^\\"]*)\"' as ip, time, method, url, request_time, request_length, status, length, ref_url, browser
| extend ts=date_parse(time, '%Y-%m-%d %H:%i:%S')
| extend __time__=cast(to_unixtime(ts) as INTEGER)
| project-away ts
| project-away content
flushers:
- Type: flusher_stdout
OnlyStdout: true
输出:{
"ip": "127.0.0.1",
"time": "07/Jul/2022:10:43:30 +0800",
"method": "POST",
"url": "PutData?Category=YunOsAccountOpLog",
"request_time": "0.024",
"request_length": "18204",
"status": "200",
"length": "37",
"ref_url": "-",
"browser": "aliyun-sdk-java",
"__time__": "1713231487"
}
正则解析+过滤
根据正则表达式解析字段,并根据解析后的字段值过滤日志。输入:
127.0.0.1 - - [07/Jul/2022:10:43:30 +0800] "POST /PutData?Category=YunOsAccountOpLog" 0.024 18204 200 37 "-" "aliyun-sdk-java"
127.0.0.1 - - [07/Jul/2022:10:44:30 +0800] "Get /PutData?Category=YunOsAccountOpLog" 0.024 18204 200 37 "-" "aliyun-sdk-java"
原有插件:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_parse_regex_native
SourceKey: content
Regex: ([\d\.]+) \S+ \S+ \[(\S+) \S+\] \"(\w+) ([^\\"]*)\" ([\d\.]+) (\d+) (\d+) (\d+|-) \"([^\\"]*)\" \"([^\\"]*)\"
Keys:
- ip
- time
- method
- url
- request_time
- request_length
- status
- length
- ref_url
- browser
- Type: processor_filter_regex_native
FilterKey:
- method
- status
FilterRegex:
- ^(POST|PUT)$
- ^200$
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| parse-regexp content, '([\d\.]+) \S+ \S+ \[(\S+) \S+\] \"(\w+) ([^\\"]*)\" ([\d\.]+) (\d+) (\d+) (\d+|-) \"([^\\"]*)\" \"([^\\"]*)\"' as ip, time, method, url, request_time, request_length, status, length, ref_url, browser
| project-away content
| where regexp_like(method, '^(POST|PUT)#39;) and regexp_like(status, '^200#39;)
flushers:
- Type: flusher_stdout
OnlyStdout: true输出:
{
"ip": "127.0.0.1",
"time": "07/Jul/2022:10:43:30",
"method": "POST",
"url": "/PutData?Category=YunOsAccountOpLog",
"request_time": "0.024",
"request_length": "18204",
"status": "200",
"length": "37",
"ref_url": "-",
"browser": "aliyun-sdk-java",
"__time__": "1713238839"
}
脱敏
将日志中的敏感信息脱敏。输入:
{"account":"1812213231432969","password":"04a23f38"}
原有插件:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_desensitize_native
SourceKey: content
Method: const
ReplacingString: "******"
ContentPatternBeforeReplacedString: 'password":"'
ReplacedContentPattern: '[^"]+'
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| parse-regexp content, 'password":"(\S+)"' as password
| extend content=replace(content, password, '******')
flushers:
- Type: flusher_stdout
OnlyStdout: true输出:
{
"content": "{\"account\":\"1812213231432969\",\"password\":\"******\"}",
"__time__": "1713239305"
}
拓展插件对比
Cloud Native
添加字段
在输出结果中添加字段,输入:
this is a test log
原有插件:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_add_fields
Fields:
service: A
IgnoreIfExist: false
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| extend service='A'
flushers:
- Type: flusher_stdout
OnlyStdout: true
输出:
{
"content": "this is a test log",
"service": "A",
"__time__": "1713240293"
}
Json 解析+丢弃字段
解析 json 并删除解析后的指定字段。输入:
{"key1": 123456, "key2": "abcd"}
原有插件:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_parse_json_native
SourceKey: content
- Type: processor_drop
DropKeys:
- key1
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| parse-json content
| project-away content
| project-away key1
flushers:
- Type: flusher_stdout
OnlyStdout: true输出:
{ "key2": "abcd",
"__time__": "1713245944"
}
Json 解析+重命名字段
解析 json 并重命名解析后的字段。输入:
{"key1": 123456, "key2": "abcd"}
原有插件:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_parse_json_native
SourceKey: content
- Type: processor_rename
SourceKeys:
- key1
DestKeys:
- new_key1
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| parse-json content
| project-away content
| project-rename new_key1=key1
flushers:
- Type: flusher_stdout
OnlyStdout: true输出:
{
"new_key1": "123456",
"key2": "abcd",
"__time__": "1713249130"
}
Json 解析+过滤日志
解析 json 并根据字段条件过滤日志。输入:
{"ip": "10.**.**.**", "method": "POST", "browser": "aliyun-sdk-java"}
{"ip": "10.**.**.**", "method": "POST", "browser": "chrome"}
{"ip": "192.168.**.**", "method": "POST", "browser": "aliyun-sls-ilogtail"}
原有插件:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_parse_json_native
SourceKey: content
- Type: processor_filter_regex
Include:
ip: "10\\..*"
method: POST
Exclude:
browser: "aliyun.*"
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| parse-json content
| project-away content
| where regexp_like(ip, '10\..*') and regexp_like(method, 'POST') and not regexp_like(browser, 'aliyun.*')
flushers:
- Type: flusher_stdout
OnlyStdout: true输出:
{
"ip": "10.**.**.**",
"method": "POST",
"browser": "chrome",
"__time__": "1713246645"
}
Json 解析+字段值映射处理
解析 json 并根据字段值的不同,映射为不同的值。输入:
{"_ip_":"192.168.0.1","Index":"900000003"}
{"_ip_":"255.255.255.255","Index":"3"}
原有插件:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_parse_json_native
SourceKey: content
- Type: processor_dict_map
MapDict:
"127.0.0.1": "LocalHost-LocalHost"
"192.168.0.1": "default login"
SourceKey: "_ip_"
DestKey: "_processed_ip_"
Mode: "overwrite"
HandleMissing": true
Missing: "Not Detected"
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| parse-json content
| project-away content
| extend _processed_ip_=
CASE
WHEN _ip_ = '127.0.0.1' THEN 'LocalHost-LocalHost'
WHEN _ip_ = '192.168.0.1' THEN 'default login'
ELSE 'Not Detected'
END
flushers:
- Type: flusher_stdout
OnlyStdout: true输出:
{
"_ip_": "192.168.0.1",
"Index": "900000003",
"_processed_ip_": "default login",
"__time__": "1713259557"
}
字符串替换
替换日志中的指定字符串。输入:
hello,how old are you? nice to meet you
原有插件:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_string_replace
SourceKey: content
Method: const
Match: "how old are you?"
ReplaceString: ""
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| extend content=replace(content, 'how old are you?', '')
flushers:
- Type: flusher_stdout
OnlyStdout: true
输出:{ "content": "hello, nice to meet you",
"__time__": "1713260499"
}
数据编码与解码
Base64
对日志进行 Base64 加密。输入:
this is a test log
原有插件:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_base64_encoding
SourceKey: content
NewKey: content1
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| extend content1=to_base64(cast(content as varbinary))
flushers:
- Type: flusher_stdout
OnlyStdout: true
输出:{ "content": "this is a test log",
"content1": "dGhpcyBpcyBhIHRlc3QgbG9n",
"__time__": "1713318724"
}
MD5
对日志进行 MD5 加密。输入:
hello,how old are you? nice to meet you
原有插件:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_string_replace
SourceKey: content
Method: const
Match: "how old are you?"
ReplaceString: ""
flushers:
- Type: flusher_stdout
OnlyStdout: true
SPL:enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| extend content1=lower(to_hex(md5(cast(content as varbinary))))
flushers:
- Type: flusher_stdout
OnlyStdout: true输出:
{
"content": "this is a test log",
"content1": "4f3c93e010f366eca78e00dc1ed08984",
"__time__": "1713319673"
}
新增能力项
Cloud Native
数学计算
输入:4。SPL:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| extend val = cast(content as double)
| extend power_test = power(val, 2)
| extend round_test = round(val)
| extend sqrt_test = sqrt(val)
flushers:
- Type: flusher_stdout
OnlyStdout: true输出:
{
"content": "4",
"power_test": 16.0,
"round_test": 4.0,
"sqrt_test": 2.0,
"val": 4.0,
"__time__": "1713319673"
}
URL 计算
URL 编码解码
输入:
https://homenew.console.aliyun.com/home/dashboard/ProductAndService
SPL:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| extend encoded = url_encode(content)
| extend decoded = url_decode(encoded)
flushers:
- Type: flusher_stdout
OnlyStdout: true
输出:
{
"content": "https://homenew.console.aliyun.com/home/dashboard/ProductAndService",
"decoded": "https://homenew.console.aliyun.com/home/dashboard/ProductAndService",
"encoded": "https%3A%2F%2Fhomenew.console.aliyun.com%2Fhome%2Fdashboard%2FProductAndService",
"__time__": "1713319673"
}
URL 提取
输入:
https://sls.console.aliyun.com:443/lognext/project/dashboard-all/logsearch/nginx-demo?accounttraceid=d6241a173f88471c91d3405cda010ff5ghdw
SPL:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| extend host = url_extract_host(content)
| extend query = url_extract_query(content)
| extend path = url_extract_path(content)
| extend protocol = url_extract_protocol(content)
| extend port = url_extract_port(content)
| extend param = url_extract_parameter(content, 'accounttraceid')
flushers:
- Type: flusher_stdout
OnlyStdout: true
输出:
{
"content": "https://sls.console.aliyun.com:443/lognext/project/dashboard-all/logsearch/nginx-demo?accounttraceid=d6241a173f88471c91d3405cda010ff5ghdw",
"host": "sls.console.aliyun.com",
"param": "d6241a173f88471c91d3405cda010ff5ghdw",
"path": "/lognext/project/dashboard-all/logsearch/nginx-demo",
"port": "443",
"protocol": "https",
"query": "accounttraceid=d6241a173f88471c91d3405cda010ff5ghdw",
"__time__": "1713319673"
}
比较&逻辑运算符
输入:
{"num1": 199, "num2": 10, "num3": 9}
SPL:
enable: true
inputs:
- Type: input_file
FilePaths:
- /workspaces/ilogtail/debug/simple.log
processors:
- Type: processor_spl
Script: |
*
| parse-json content
| extend compare_result = cast(num1 as double) > cast(num2 as double) AND cast(num2 as double) > cast(num3 as double)
flushers:
- Type: flusher_stdout
OnlyStdout: true
输出:{ "compare_result": "true",
"content": "{\"num1\": 199, \"num2\": 10, \"num3\": 9}",
"num1": "199",
"num2": "10",
"num3": "9",
"__time__": "1713319673"
}
其他
更多能力请参考:https://help.aliyun.com/zh/sls/user-guide/function-overview
欢迎大家补充更多 iLogtail SPL 实践案例!
相关推荐
- 面试官:来,讲一下枚举类型在开发时中实际应用场景!
-
一.基本介绍枚举是JDK1.5新增的数据类型,使用枚举我们可以很好的描述一些特定的业务场景,比如一年中的春、夏、秋、冬,还有每周的周一到周天,还有各种颜色,以及可以用它来描述一些状态信息,比如错...
- 一日一技:11个基本Python技巧和窍门
-
1.两个数字的交换.x,y=10,20print(x,y)x,y=y,xprint(x,y)输出:102020102.Python字符串取反a="Ge...
- Python Enum 技巧,让代码更简洁、更安全、更易维护
-
如果你是一名Python开发人员,你很可能使用过enum.Enum来创建可读性和可维护性代码。今天发现一个强大的技巧,可以让Enum的境界更进一层,这个技巧不仅能提高可读性,还能以最小的代价增...
- Python元组编程指导教程(python元组的概念)
-
1.元组基础概念1.1什么是元组元组(Tuple)是Python中一种不可变的序列类型,用于存储多个有序的元素。元组与列表(list)类似,但元组一旦创建就不能修改(不可变),这使得元组在某些场景...
- 你可能不知道的实用 Python 功能(python有哪些用)
-
1.超越文件处理的内容管理器大多数开发人员都熟悉使用with语句进行文件操作:withopen('file.txt','r')asfile:co...
- Python 2至3.13新特性总结(python 3.10新特性)
-
以下是Python2到Python3.13的主要新特性总结,按版本分类整理:Python2到Python3的重大变化Python3是一个不向后兼容的版本,主要改进包括:pri...
- Python中for循环访问索引值的方法
-
技术背景在Python编程中,我们经常需要在循环中访问元素的索引值。例如,在处理列表、元组等可迭代对象时,除了要获取元素本身,还需要知道元素的位置。Python提供了多种方式来实现这一需求,下面将详细...
- Python enumerate核心应用解析:索引遍历的高效实践方案
-
喜欢的条友记得关注、点赞、转发、收藏,你们的支持就是我最大的动力源泉。根据GitHub代码分析统计,使用enumerate替代range(len())写法可减少38%的索引错误概率。本文通过12个生产...
- Python入门到脱坑经典案例—列表去重
-
列表去重是Python编程中常见的操作,下面我将介绍多种实现列表去重的方法,从基础到进阶,帮助初学者全面掌握这一技能。方法一:使用集合(set)去重(最简单)pythondefremove_dupl...
- Python枚举类工程实践:常量管理的标准化解决方案
-
本文通过7个生产案例,系统解析枚举类在工程实践中的应用,覆盖状态管理、配置选项、错误代码等场景,适用于Web服务开发、自动化测试及系统集成领域。一、基础概念与语法演进1.1传统常量与枚举类对比#传...
- 让Python枚举更强大!教你玩转Enum扩展
-
为什么你需要关注Enum?在日常开发中,你是否经常遇到这样的代码?ifstatus==1:print("开始处理")elifstatus==2:pri...
- Python枚举(Enum)技巧,你值得了解
-
枚举(Enum)提供了更清晰、结构化的方式来定义常量。通过为枚举添加行为、自动分配值和存储额外数据,可以提升代码的可读性、可维护性,并与数据库结合使用时,使用字符串代替数字能简化调试和查询。Pytho...
- 78行Python代码帮你复现微信撤回消息!
-
来源:悟空智能科技本文约700字,建议阅读5分钟。本文基于python的微信开源库itchat,教你如何收集私聊撤回的信息。[导读]Python曾经对我说:"时日不多,赶紧用Python"。于是看...
- 登录人人都是产品经理即可获得以下权益
-
文章介绍如何利用Cursor自动开发Playwright网页自动化脚本,实现从选题、写文、生图的全流程自动化,并将其打包成API供工作流调用,提高工作效率。虽然我前面文章介绍了很多AI工作流,但它们...
- Python常用小知识-第二弹(python常用方法总结)
-
一、Python中使用JsonPath提取字典中的值JsonPath是解析Json字符串用的,如果有一个多层嵌套的复杂字典,想要根据key和下标来批量提取value,这是比较困难的,使用jsonpat...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- python计时 (73)
- python安装路径 (56)
- python类型转换 (93)
- python自定义函数 (53)
- python进度条 (67)
- python吧 (67)
- python字典遍历 (54)
- python的for循环 (65)
- python格式化字符串 (61)
- python串口编程 (60)
- python读取文件夹下所有文件 (59)
- java调用python脚本 (56)
- python操作mysql数据库 (66)
- python字典增加键值对 (53)
- python获取列表的长度 (64)
- python接口 (63)
- python调用函数 (57)
- python人脸识别 (54)
- python多态 (60)
- python命令行参数 (53)
- python匿名函数 (59)
- python打印九九乘法表 (65)
- python赋值 (62)
- python异常 (69)
- python元祖 (57)