LoadRunner性能测试详解·下

|----------------|
| 你好,我是安然无虞。 |

文章目录

常用函数

对于常用的函数, 我们要比较熟悉, 有不清楚的地方, 记得查询官网帮助, 以下是官网在线文档, 非常具有参考价值:

  1. LR 函数参考

  2. C 语言函数参考

  3. LR 常用函数参考(C语言)

  4. LR 常用函数参考(Java)

  5. LR 常用函数参考(JavaScript)

参数类函数

1.lr_eval_string

功能: 将参数转化为字符串.

用法示例:

c 复制代码
Action()
{
	lr_save_int(0, "searchCount");
  lr_save_string("我是字符串", "str1");
  lr_output_message("Is zero, %s", lr_eval_string("{str1}"));
  
	if (atoi(lr_eval_string("{searchCount}") ) == 0) {
	
		lr_output_message("Is zero, %s",  lr_eval_string("{searchCount}"));
    }

	lr_save_int(47, "searchCount");
	if (atoi(lr_eval_string("{searchCount}") ) != 0) {
		lr_output_message("Not zero, %s",  lr_eval_string("{searchCount}"));
    }

	return 0;
}

2.lr_eval_json

功能: 将字符串或者文件转换为Json对象.

用法示例:

c 复制代码
TestEval()
{
	char* json_input = "{"
		"\"firstName\": \"John\","
		"\"lastName\": \"Smith\","
		"\"address\": {"
		"    \"streetAddress\":\"21 2nd Street\","
		"    \"city\":\"New York\","
		"    \"state\":\"NY\","
		"    \"postalCode\":\"10021\""
		"}"		
		"}";
	lr_save_string(json_input, "JSON_Input_Param");
	
	// 创建json对象(通过字符串)
	lr_eval_json("Buffer={JSON_Input_Param}",
	             "JsonObject=json_obj_1", LAST);
	
	// 创建json对象(通过文件)
	lr_eval_json("Buffer/File=store.json", 
	             "JsonObject=json_obj_2", LAST);
  
  // 修改json对象值
  lr_json_set_values("JsonObject=json_obj_1", "Value=test1111111", "QueryString=$.firstName", "SelectAll=Yes", Last);
  
  // 取得json对象值
  lr_json_get_values("JsonObject=json_obj_1", 
                    "ValueParam=test_result", "QueryString=$.firstName", Last);
  
  // json对象转换成json字符串
  lr_json_stringify("JsonObject=json_obj_1", "Format=compact", "OutputParam=Result", Last);
  
  // 打印结果
  lr_log_message("%s--%s", lr_eval_string("{test_result}"), lr_eval_string("{Result}"));
	
	return 0;
}

3.lr_json_set_values

功能: 修改json对象中的值.

用法示例: 同上

4.lr_json_get_values

功能: 获取json对象中的值.

用法示例: 同上

5.lr_json_stringify

功能: 将json对象转换成json字符串.

用法示例: 同上

6.lr_save_string

功能: 将变量以字符串类型存入参数.

用法示例:

c 复制代码
char str1[100] = "我是测试字符串";
lr_save_string(str1, "param1");
lr_log_message("%s", lr_eval_string("{param1}"));

7.lr_save_int

功能: 将变量以数字类型存入参数.

用法示例:

c 复制代码
int n = 1314;
lr_save_int(n, "param1");
lr_log_message("%s", lr_eval_string("{param1}"));

8.lr_save_datetime

功能: 时间格式化, 精确到秒, 存入参数.

用法示例:

c 复制代码
lr_save_datetime("%Y-%m-%d %H:%M:%S", TIME_NOW, "currDateTime");
lr_output_message(lr_eval_string("{currDateTime}"));

9.lr_save_timestamp

功能: 将时间戳存入到参数, 可精确到秒, 毫秒, 微秒.

用法示例:

c 复制代码
// 以秒为单位
lr_save_timestamp("param", "DIGITS=10", LAST);
lr_output_message(lr_eval_string("{param}"));

//以毫秒为单位
lr_save_timestamp("param", LAST);
lr_output_message(lr_eval_string("{param}"));

//以微秒为单位
lr_save_timestamp("param", "DIGITS=16", LAST);
lr_output_message(lr_eval_string("{param}"));

输出示例:

10.web_save_timestamp_param

功能: 将时间戳存入到参数, 固定为毫秒.

用法示例:

c 复制代码
web_save_timestamp_param("tStamp", LAST );//默认以毫秒为单位,将时间戳存入参数
lr_output_message(lr_eval_string("Timestamp: {tStamp}"));

11.lr_param_sprintf

功能: 格式话字符串, 类似 sprintf

用法示例:

c 复制代码
int index = 56;
char* suffix = "txt";
// 底层采用 C语言 的 sprintf 函数
lr_param_sprintf ("LOG_NAME_PARAM", "log_%d.%s", index, suffix,100);
lr_output_message("The new file name is %s",lr_eval_string("{LOG_NAME_PARAM}"));

输出示例:

12.lr_convert_string_encoding

功能: 编码转换, 可防止中文乱码.

用法示例:

c 复制代码
lr_convert_string_encoding("我是中文", LR_ENC_SYSTEM_LOCALE,LR_ENC_UTF8,"ReplyMessage");

检查关联类函数

该类函数一般放在 web actions 函数的前面.

1.web_reg_find

功能: 在行动函数前面搜索指定字符串, 默认找不到则失败.

用法示例:

c 复制代码
// 搜索指定字符串
web_reg_find("Search=Body",
	"Text=devt_token",
	LAST);

// 搜索指定字符串(开始+结束)
web_reg_find("Search=Body",
	"TextPfx=\"devt_token\":\"",
	"TextSfx=\"",
	LAST);

// 通配搜索
web_reg_find("Text/ALNUMLC=\"devt_toke^\"",
	LAST);
web_custom_request("login.do_3",
	"URL={host}/devt-service/api/login.do",
	"Method=POST",
	"Resource=0",
	"RecContentType=application/json",
	"Referer={host}/devt-web/",
	"Snapshot=t290.inf",
	"Mode=HTML",
	"EncType=application/json",
	"Body=	{\"acctName\":\"admin\",\"acctPwd\":\"11111111\",\"typ	e\":\"0\"}",
	LAST);

2.web_reg_save_param

功能: 将动态数据注册到参数.

用法示例:

c 复制代码
//从服务端返回中取得数据,支持双右边界
web_reg_save_param("devtToken",
	"LB=\"devt_token\":\"",
	"RB=\"",
	LAST);
web_custom_request("login.do_3",
	"URL={host}/devt-service/api/login.do",
	"Method=POST",
	"Resource=0",
	"RecContentType=application/json",
	"Referer={host}/devt-web/",
	"Snapshot=t290.inf",
	"Mode=HTML",
	"EncType=application/json",
	"Body=	{\"acctName\":\"admin\",\"acctPwd\":\"11111111\",\"type\":\"0\"}",
	LAST);

lr_log_message("取得数据为: %s", lr_eval_string("{devtToken}"));

3.web_reg_save_param_regexp

功能: 将动态数据注册到参数, 比 web_reg_save_param函数功能强大.

用法示例:

c 复制代码
//从服务端返回中取得数据
web_reg_save_param_regexp(
	"ParamName=devtToken",
	"RegExp=(\"devt_token\":\".*?\")",
	"Group=0",
	SEARCH_FILTERS,
	"Scope=BODY",
	LAST);
web_custom_request("login.do_3",
	"URL={host}/devt-service/api/login.do",
	"Method=POST",
	"Resource=0",
	"RecContentType=application/json",
	"Referer={host}/devt-web/",
	"Snapshot=t290.inf",
	"Mode=HTML",
	"EncType=application/json",
	"Body=	{\"acctName\":\"admin\",\"acctPwd\":\"11111111\",\"type\":\"0\"}",LAST);

lr_log_message("取得 token 为:%s",lr_eval_string("{devtToken}"));

4.web_reg_save_param_json

功能: 以 json 方式解析动态数据并注册到参数 (要求数据为json格式).

用法示例:

c 复制代码
//从服务端返回中取得数据
web_reg_save_param_json(
	"ParamName=devtToken",
	"QueryString=$..devt_token",
	SEARCH_FILTERS,
	"Scope=BODY",
	LAST);

5.web_reg_save_param_xpath

功能: 以 xpath 方式解析动态数据并注册到参数 (要求数据为XML格式).

用法示例:

c 复制代码
web_reg_save_param_xpath( 			"ParamName=CorrelationParameter",                    "QueryString=/LR_EXTENSION[1]/object[1]/object[1]/array[1]", 
	"DFEs=JsonXml", 
	"ReturnXML=Yes", 
	SEARCH_FILTERS, 
	"Scope=Body", 
	LAST);

6.web_reg_save_param_attrib

功能: 以 html 文档方式解析动态数据并注册到参数.

用法示例:

c 复制代码
//<INPUT TYPE="HIDDEN" NAME="field1" VALUE="Usj3xEEneBBTcIi6IXNHBBaz7D7ytfDmmbgOKjVuc59C">

web_reg_save_param_attrib(
	"ParamName=param1",
	"TagName=input",
	"Extract=value",
	"Name=field1",
	"Type=*",
	SEARCH_FILTERS,
	"IgnoreRedirections=No",
	LAST);

日志类函数

1.lr_output_message

功能: 向日志文件、输出窗口和其他测试报告摘要发送消息.

用法示例:

c 复制代码
lr_output_message("取得token为: %s", lr_eval_string("{devtToken}"));

2.lr_log_message

功能: 向日志文件发送消息.

用法示例:

c 复制代码
lr_log_message("取得token为: %s", lr_eval_string("{devtToken}"));

3.lr_debug_message

功能: 向日志文件发送调试信息 (需要设置日志级别).

用法示例:

c 复制代码
lr_debug_message((LR_MSG_CLASS_RESULT_DATA | LR_MSG_CLASS_PARAMETERS, lr_eval_string("1111{devtToken}"));

4.lr_error_message

功能: 向日志文件发送错误消息 (红色显示).

用法示例:

c 复制代码
lr_error_message("取得token为: %s", lr_eval_string("{devtToken}");

行动类函数

1.web_rest

功能: 使用 HTTP 支持的任何方法发送 REST API 请求.

用法示例:

  • 基本上录制脚本的时候都是以该函数生成, 可参考录制脚本中的样例或者官网说明.
c 复制代码
//Get
web_rest("get all customers info",
	"URL=http://myServer/customers?limit={limit}&offset=	{offset}",
	"Method=GET",
	LAST);

//Put
web_rest("update customer info",
	"URL=http://myServer/customers/{cust_id}",
	"Method=PUT",
	"ResType=JSON",
	"Body={ \"address\":\"yyyy\", ... }",
	LAST);

//Post
web_rest("create new customer",
	"URL=http://myServer/customers/",
	"Method=POST",
	"ResType=JSON",
	"Body = { \"name\":\"john\", \"address\":\"xxxx\", ... 	}", /* BodyFile for large content */
	LAST);

//Delete
web_rest("delete customer",
	"URL=http://www.example.com/customers/{cust_id}",
	"Method=DELETE",
	LAST);

2.web_custom_request

功能: 允许使用 HTTP 支持的任何方法创建自定义的HTTP请求.

用法示例: 同上类似

常用C函数

1.sprintf

功能: 格式话字符串.

用法示例:

c 复制代码
char* param1="I am param1!";
char* param2="I am param2!";
int num1=123;
char dest[100];
sprintf(dest,"%s %s %d",param1,param2,num1);
lr_log_message(dest);

输出示例:

2.strcat

功能: 连接两个字符串.

用法示例:

c 复制代码
char fullpath[1024];
char * filename = "logfile.txt";
strcpy(fullpath, "c:\\tmp");
strcat(fullpath, "\\");
strcat(fullpath, filename);
lr_output_message ("当前文件路径为 %s", fullpath);

输出示例:

3.strchr

功能: 查找第一次出现的字符.

用法示例:

c 复制代码
char* string = "His Excellency the Duke of Exeter";
char* first_x, *last_x;
first_x = (char*)strchr(string, 'x');
lr_output_message ("第一次出现的字符 x: %s", first_x);

last_x = (char*)strrchr(string, 'x');
lr_output_message ("最后一次出现的字符 x: %s", last_x);

输出示例:

4.strcmp

功能: 比较两个字符串的字母顺序, 可用于判断是否相等.

5.strcpy

功能: 将一个字符串复制到另一个字符串(注意哦, 是复制不是在字符串末尾追加).

用法示例:

c 复制代码
char fullpath[1024], * filename = "logfile.txt";
strcpy(fullpath, "c:\\tmp");
lr_output_message("fullpath after strcpy: %s", fullpath);

输出示例:

6.stricmp

功能: 对两个字符串进行不区分大小写的比较.

用法示例:

c 复制代码
int result;
char tmp[20];
char string1[] = "The quick brown dog jumps over the lazy fox";
char string2[] = "The QUICK brown dog jumps over the lazy fox";
result = stricmp(string1, string2);
if (result > 0)
	strcpy(tmp, "greater than");
else if (result < 0)
	strcpy(tmp, "less than");
else
	strcpy(tmp, "equal to");

lr_output_message ("strcmp: String 1 is %s string 2", tmp);

7.strlen

功能: 返回字符串的长度.

用法示例:

c 复制代码
int is_digit, i = 0;
char* str = "1234567k89";
unsigned int len = strlen(str);
do {
	if (i == len) {
		lr_output_message ("No letters found in string");
		return -1;
	}
	is_digit = isdigit(str[i++]);
}
while (is_digit);

lr_output_message ("The first letter appears in character %d of string", i);

8.strncat

功能: 把 src 所指向的字符串追加到 dest 所指向的字符串的结尾, 直到 n 字符长度为止.

用法示例:

c 复制代码
char src[50], dest[50];
strcpy(src, "This is source");
strcpy(dest, "This is destination");
strncat(dest, src, 5);
lr_log_message("最终的目标字符串: |%s|", dest);

9.strncmp

功能: 把 str1 和 str2 进行比较, 最多比较前 n 个字节.

用法示例:

c 复制代码
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = strncmp(str1, str2, 4);
if(ret < 0) {
	lr_log_message("str1 小于 str2");
} else if(ret > 0) {
	lr_log_message("str2 小于 str1");
} else {
	lr_log_message("str1 等于 str2");
}

10.strncpy

功能: 把 src 所指向的字符串复制到 dest, 最多复制 n 个字符.

用法示例:

c 复制代码
char src[40];
char dest[12];
memset(dest, '\0', sizeof(dest));
strcpy(src, "This is runoob.com");
strncpy(dest, src, 10);
lr_log_message("最终的目标字符串: %s\n", dest);

11.strnicmp

功能: 把 str1 和 str2 进行不区分大小写比较, 最多比较前 n 个字节.

用法示例:

c 复制代码
int result;
char tmp[20];
char string1[] = "The quick brown dog jumps over the lazy fox";
char string2[] = "The quick brown DOG jumps over one lazy fox";
result = strnicmp( string1, string2 ,10);
if (result > 0)
	strcpy(tmp, "greater than");
else if (result < 0)
	strcpy(tmp, "less than");
else
	strcpy(tmp, "equal to");

lr_output_message ("stricmp: String 1 is %s string 2", tmp);

12.strrchr

功能: 查找最后一次出现的字符.

用法示例:

c 复制代码
char* string = "His Excellency the Duke of Exeter";
char* first_x, *last_x;
first_x = (char*)strchr(string, 'x');
lr_output_message ("第一次出现的字符 x: %s", first_x);
last_x = (char*)strrchr(string, 'x');
lr_output_message ("最后一次出现的字符 x: %s", last_x);

13.strspn

功能: 该函数返回一个 str1 中第一个 不在 str2 中出现的字符下标.

用法示例:

c 复制代码
int len;
const char str1[] = "ABCDEFG019874";
const char str2[] = "ABCD";
len = strspn(str1, str2);
lr_log_message("初始段匹配长度 %d\n", len );

输出示例:

14.strstr

功能: 在字符串 str1 中查找第一次出现字符串 str2 的位置, 不包含终止符.

用法示例:

c 复制代码
int offset;
char* position;
char* str = "The quick brown dog jumps over the lazy fox";
char* search_str = "dog";
position = (char*)strstr(str, search_str);
offset = (int)(position - str + 1);

lr_output_message ("The string \"%s\" was found at position %d", search_str, offset);

输出示例:

15.strtok

功能: 分解字符串 str 为一组字符串, delim 为分隔符.

用法示例:

c 复制代码
char path[] = "c:\\microfocus\\lrun\\bin\\wlrun.exe";
char separators[] = ".\\";
char* token;
// Get the first token
token = (char*)strtok(path, separators);
if (!token) {
	lr_output_message ("No tokens found in string!");
	return( -1 );
}
// While valid tokens are returned
while (token != NULL ) {
	lr_output_message ("%s", token );
	// Get the next token
	token = (char*)strtok(NULL, separators);
}

输出结果:

lr语言编程

1.基础语法

LoadRunner12 默认为C语言, 同时支持Java和JavaScript, 建议大家主要学习C语言, 毕竟性能最高.

所以这里的讲解均以 C语言为基础.

2.变量使用

LoadRunner中的变量 其实就是C语言中的变量, 不过有以下几点约束:

  1. 变量可以定义在.h头文件中
  2. 变量可以定义在Action函数外部
  3. 变量可以定义在Action开始的部分
  4. Action体内不可以定义变量, 会编译报错

代码示例:

c 复制代码
int a1=0;
int a2=0;
char* p1;
char str2[]="string111111222";

Action()
{
	lr_log_message("%s",&str2[5]);
	p1=lr_eval_string("{param1}");
	lr_log_message("%s",p1);
	//int a3=0;//此处编译会报错
	return 0;
}

3.参数操作

参数是LoadRunner中的一个概念.

参数可以认为是C语言中的一个全局变量, 我们在写脚本的时候, 要学会用参数化的思想去解决问题.

  1. 字符串参数类操作
c 复制代码
char str1[]="str111";
//参数的取值
lr_log_message("%s",lr_eval_string("{param1}"));
lr_log_message("%s",lr_eval_string("{param2}"));
//参数的赋值
lr_save_string(str1,"param1");
lr_save_string("new param2","param2");
//参数的取值
lr_log_message("%s",lr_eval_string("{param1}"));
lr_log_message("%s",lr_eval_string("{param2}"));
  1. int参数类操作
c 复制代码
//参数的取值
lr_log_message("%s",lr_eval_string("{param1}"));
lr_log_message("%s",lr_eval_string("{param2}"));
//参数的赋值
lr_save_int(11,"param1");
lr_save_int(22,"param2");
//参数的取值
lr_log_message("%s",lr_eval_string("{param1}"));
lr_log_message("%s",lr_eval_string("{param2}"));

4.参数变量互转

参数与变量相互转换, 注意参数统一格式为字符.

c 复制代码
char str1[]="str111";
char format1[200]="";
int n1=0;
//参数转字符串变量
strcpy(str1, lr_eval_string("{param1}"));
lr_output_message("%s", str1);

//参数转数值变量(参数统一为字符,故先转 int)
n1=atoi(lr_eval_string("{param2}"));
lr_output_message("%d", n1);

//格式化参数
sprintf(format1,"%s---%d",str1,n1);
lr_log_message("%s",format1);

//参数转参数
lr_save_string(lr_eval_string("{param1}"),"param2");

5.逻辑控制

C语言中的顺序、分支、循环 同样适用于 LoadRunner.

C语言中的函数同样可以在 LoadRunner 中使用.

LR中的函数可以定义在Action外部, 也可以定义在.h头文件中.

c 复制代码
void say(int flag){
	if(flag==0){
		lr_log_message("我是偶数");
	}else{
		lr_log_message("我是奇数");
	}
}

Action() {
	int i=0;
	for(i=0;i<10;i++){
		if(i%2==0){
			say(0);
		}else{
			say(1);
	}
}
	return 0;
}

6.JavaScript脚本

在C语言的脚本中我们可以通过 web_js_run函数 来运行一些 JS脚本, 使用 JS语言 可以快速写出非常强大的语言.

举个小例子:

  1. 准备 js1.js (直接放在工作目录下)
javascript 复制代码
function test1(){
	return new Date().getTime();
}
function test2(a,b){
	return a+b;
}
  1. 准备 js2.js (直接放在工作目录下)
javascript 复制代码
function test3() {
	var user = '{ "id": 1, "name": "longge1" }';
	var tuser = JSON.parse(user);
	return tuser.name;
}
  1. LR 主要脚本如下:
c 复制代码
Action{
  web_js_run("Code=test3()",
		"ResultParam=jsVal",
		SOURCES,"File=js1.js",
		ENDITEM,"File=js2.js",
		ENDITEM,
		LAST);
  
	lr_log_message("%s",lr_eval_string("{jsVal}"));
}

我们之前在录制脚本的时候, 选择的都是 C语言作为主体脚本, 其实JavaScript 也可以作为录制的主体脚本语言.

实战练习

实战1: 唯一序列

需求: 在一些场景压测时, 需要唯一序列号, 我们可以采用如下思路实现

思路: 让每一个 Vuser 的序列统一采用 VuserID+时间戳 (时间戳不重复)

过程数据模拟:

脚本:

c 复制代码
char seq[20];
// 取唯一序列
char* GetSeq(){
	// 先取第一个 Vuser 唯一前缀,保证不同线程之间不冲突
  // start是内置参数UserID类型
	char* start = lr_eval_string("{start}");
  // 将毫秒级时间戳存入参数tamp中
	web_save_timestamp_param("tamp",LAST);
	// 保证线程内部不冲突
	sleep(1);
  
  // 注意哦这里不是数字相加, 而是字符串拼接
	sprintf(seq,"%s%s",lr_eval_string("	{start}"),lr_eval_string("{tamp}"));
	return seq;
}

Action()
{
	int i=0;
	for(i=0; i<100; i=i+1)
	{
		lr_log_message("%s",GetSeq());
	}
	return 0;
}

实战2: 登陆脚本

要求: 录制一套完整的脚本, 内容包括登陆动作:

  1. 登陆逻辑放置在 actions 里面
  2. 易变的常量实现参数化 (主机、用户名、密码、端口...)
  3. 登陆实现规则关联
  4. 登陆采用5个以上账号

首先, 录制登陆脚本:

然后将易变的常量实现参数化:

其中主机和端口因为是固定的, 所以可以设计成Custom自定义类型, 而这里要5个用户, 所以用户名和密码需要分别设计为File文件类型:

实现之后的脚本:

这里我们将其放到一个事务中, 并将动态数据注册到参数 devtToken 中, 用来检查是否登陆成功:

然后在最后判断事务是否正常退出:

实战3: 单查询脚本

要求: 录制一套完整的脚本, 内容包括至少一个单查询:

  1. 登陆放置在 init 里面, 退出放置在end, 核心逻辑放置在 actions 里面
  2. 易变的常量实现参数化 (主机、用户名、密码、端口...)
  3. 登陆实现规则关联
  4. 选择一个查询条件设计为20种以上组合
  5. 查询设置为一个事务, 并采用业务判断成功与否

登录功能和前面的类似, 这里的 qryText 是 File文件类参数, 里面的内容是 查询文本.

登录成功后需要为后续的请求添加请求头 Authorization, 所以需要使用 web_add_auto_header()函数.

这里我们虽然也使用了事务, 但是采用的是结果断言的方式: web_reg_find()函数, 判断请求是否成功, 所以这里的事务可以不用检查结果, 自动结束.

实战4: 入库脚本

要求: 录制一套完整的脚本, 内容包括一次提交动作:

  1. 登陆放置在 init 里面, 推出放置在 end, 核心逻辑放置在 actions 里面
  2. 易变的常量实现参数化 (主机、用户名、密码、端口...)
  3. 登陆实现规则关联
  4. 入库内容 (如发布消息) 采用自定义函数模拟生成
  5. 入库设置为一个事务, 并采用业务判断成功与否

其中自定义函数GetTitle()用于生成不同的标题, 并且以字符串文本的形式存入title参数中, 这样一来发布不同的消息请求 标题内容都是变化的:

|----------------------|
| 遇见安然遇见你,不负代码不负卿。 |
| 谢谢老铁的时间,咱们下篇再见~ |

相关推荐
信看1 小时前
CM4树莓派开机功能-1️⃣固定网卡
开发语言·python
帮帮志1 小时前
Jupyter使用的快捷键大全
ide·python·jupyter
qq_463944861 小时前
Jupyter中输入标题的方法
ide·python·jupyter
Blossom.1181 小时前
基于Qwen2-VL+LayoutLMv3的智能文档理解系统:从OCR到结构化知识图谱的落地实践
开发语言·人工智能·python·深度学习·机器学习·ocr·知识图谱
diegoXie1 小时前
PCRE Lookaround (零宽断言)总结(R & Python 通用)
开发语言·python·r语言
core5121 小时前
Google A2A (Agent-to-Agent) 协议实战 —— 用 Python 构建“智能体互联网”
python·agent·a2a
zoujiahui_20181 小时前
使用venv命令创建和使用python环境
开发语言·python
资深低代码开发平台专家1 小时前
Python自动化:一键搞定“文件批量重命名”
python
追光天使1 小时前
Python的后端框架
python