Json文件解析(下)

代码地址:https://github.com/nlohmann/json

 

STL容器转换

任何序列容器(std::array,std::vector,std::deque,std::forward_list,std::list),其值可以被用于构建JSON值(例如,整数,浮点数,布尔值,字符串类型,或者再次在本节中描述STL容器)可被用于创建JSON阵列。这同样适用于类似的关联容器(std::set,std::multiset,std::unordered_set,std::unordered_multiset),但是在这些情况下,数组中的元素的顺序取决于元素是如何在各个STL容器排序。

std ::矢量< INT > c_vector { 1,2,3,4 };

json j_vec(c_vector);

// [1、2、3、4]

std ::双端队列< 双 > c_deque { 1.2,2.3,3.4,5.6 };

json j_deque(c_deque);

// [1.2、2.3、3.4、5.6]

std :: list < bool > c_list { true,true,false,true };

json j_list(c_list);

// [true,true,false,true]

std ::修饰符Modifiers < 的int64_t > c_flist { 12345678909876,23456789098765,34567890987654,45678909876543 };

json j_flist(c_flist);

// [12345678909876、23456789098765、34567890987654、45678909876543]

std ::阵列< 无符号 长,4 > c_array {{ 1,2,3,4 }};

json j_array(c_array);

// [1、2、3、4]

std :: set <std :: string> c_set { “一个”,“两个”,“三个”,“四个”,“一个” };

json j_set(c_set); //仅使用“一个”的一个条目

// // [“四个”,“一个”,“三个”,“两个”]

std :: unordered_set <std :: string> c_uset { “一”,“二”,“三”,“四”,“一” };

json j_uset(c_uset); //仅使用“一个”的一个条目

// //可能是[“两个”,“三个”,“四个”,“一个”]

std :: multiset <std :: string> c_mset { “一个”,“两个”,“一个”,“四个” };

json j_mset(c_mset); //使用两个用于“一个”的条目

//也许[[一个”,“两个”,“一个”,“四个”]

std :: unordered_multiset <std :: string> c_umset { “一”,“二”,“一”,“四” };

json j_umset(c_umset); //使用两个用于“一个”的条目

//也许[[一个”,“两个”,“一个”,“四个”]

同样,任何缔键值容器(std::map,std::multimap,std::unordered_map,std::unordered_multimap),其键可以构造一个std::string,并且其值可以被用于构建JSON值(见上文实施例)可用于创建一个JSON对象。请注意,在使用多图的情况下,JSON对象中仅使用一个键,并且该值取决于STL容器的内部顺序。

std :: map <std :: string,int > c_map {{ “一个”,1 },{ “两个”,2 },{ “三个”,3 }};

json j_map(c_map);

// {“一个”:1,“三个”:3,“两个”:2}

std :: unordered_map < const  char *,double > c_umap {{ “一个”,1.2 },{ “两个”,2.3 },{ “三个”,3.4 }};

json j_umap(c_umap);

// {“一个”:1.2,“两个”:2.3,“三个”:3.4}

std :: multimap <std :: string,bool > c_mmap {{ “一个”,true },{ “两个”,true },{ “三个”,false },{ “三个”,true }};

json j_mmap(c_mmap); //仅使用键“三”的一个条目

// //也许{“一个”:true,“两个”:true,“三个”:true}

std :: unordered_multimap <std :: string,bool > c_ummap {{ “一”,true },{ “二”,true },{ “三”,false },{ “三”,true }};

json j_ummap(c_ummap); //仅使用键“三”的一个条目

// //也许{“一个”:true,“两个”:true,“三个”:true}

JSON指针和JSON补丁

该库支持JSON指针RFC 6901)作为解决结构化值的替代方法。除此之外,JSON PatchRFC 6902)允许描述两个JSON值之间的差异-有效地允许Unix已知的patch和diff操作。

// JSON值

json j_original = R“( {{

” baz“:[” one“,” two“,” three“],

” foo“:” bar“

} )” _json;

//使用JSON指针(RFC 6901)访问成员

j_original [ “ / baz / 1 ” _json_pointer];

// “两个”

//一个JSON修补程序(RFC 6902)

json j_patch = R“( [[

{” op“:” replace“,” path“:” / baz“,” value“:” boo“},

{” op“:” add “,” path“:” / hello“,” value“:[” world“]},

{” op“:” remove“,” path“:” / foo“}

] )” _json;

//应用补丁

json j_result = j_original.patch(j_patch);

// {

//     “ baz”:“ boo”,

//     “ hello”:[“ world”]

// }

//根据两个JSON值计算JSON补丁

json :: diff(j_result,j_original);

// [

//    {“ op”:“ replace”,“ path”:“ / baz”,“ value”:[“ one”,“ Two”,“ three”]},

//    {“ op”:“ remove“,” path“:” / hello“},

//    {” op“:” add“,” path“:” / foo“,” value“:” bar“}

// ]

JSON合并补丁

该库支持JSON合并补丁RFC 7386)作为补丁格式。没有使用JSON指针(请参见上文)来指定要操作的值,而是使用一种语法来描述更改,该语法与拟修改的文档非常相似。

// JSON值

json j_document = R“( {

” a“:” b“,

” c“:{

” d“:” e“,

” f“:” g“

}

}} )” _json;

//补丁

json j_patch = R“( {

” a“:” z“,

” c“:{

” f“:null

}

} )” _json;

//应用补丁

j_document.merge_patch(j_patch);

// {

//   “ a”:“ z”,

//   “ c”:{

//     “ d”:“ e”

//   }

// }

隐式转换

支持的类型可以隐式转换为JSON值。

建议不要使用隐式转换一个JSON值。可以在此处找到有关此建议的更多详细信息。

//字符串

std :: string s1 = “世界好!” ;

json js = s1;

自动 s2 = js.get <std :: string>();

//不推荐

std :: string s3 = js;

std :: string s4;

s4 = js;

//布尔

值bool b1 = true ;

json jb = b1;

自动 b2 = jb.get < bool >();

//不推荐

bool b3 = jb;

布尔 b4;

b4 = jb;

//数字

int i = 42 ;

json jn = i;

自动 f = jn.get < double >();

//不推荐使用

double f2 = jb;

双 f3;

f3 = jb;

//等

请注意,char类型不会自动转换为JSON字符串,而是自动转换为整数。必须明确指定转换为字符串:

char ch = ' A ' ;                       // ASCII值65

json j_default = ch;                 //存储整数65

json j_string = std :: string(1,ch);  //存储字符串“ A”

任意类型转换

每种类型都可以用JSON序列化,而不仅仅是STL容器和标量类型。通常,会按照以下方式进行操作:

名称空间 ns {

// //一个简单的结构,用于对人员进行建模

struct  person {

std :: string名称;

std :: string地址;

INT年龄;

};

}

ns :: person p = { “ Ned Flanders ”,“ 744 Evergreen Terrace ”,60 };

//转换为JSON:将每个值复制到JSON对象中

json j;

j [ “ name ” ] = p.name;

j [ “ address ” ] = p.address;

j [ “ age ” ] = p.age;

// ...

//从JSON转换:复制JSON对象中的每个值

ns :: person p {

j [ “ name ” ]。得到 <std :: string>(),

j [ “ address ” ]。得到 <std :: string>(),

j [ “年龄” ]。获取 < int >()

};

可以工作,但是有很多样板...幸运的是,有更好的方法:

//创建一个人

ns :: person p { “ Ned Flanders ”, “ 744 Evergreen Terrace ”, 60 };

//转换:person-> json

json j = p;

std :: cout << j << std :: endl;

// {“地址”:“ 744 Evergreen Terrace”,“年龄”:60,“名称”:“ Ned Flanders”}

//转换:

json- > person auto p2 = j.get <ns :: person>();

//就是

断言(p == p2);

基本用法

要使与一种类型一起使用,只需提供两个功能:

使用 nlohmann :: json;

命名空间 ns {

void  to_json(json&j,const person&p){

j = json {{ “ name ”,p。名称 },{ “地址”,第 地址 },{ “年龄”,第 年龄 }};

}

无效 from_json(const json&j,person&p){

j。在(“名称”)。get_to(第名);

j。在(“地址”)。get_to(第地址);

j。在(“年龄”)。get_to(第年龄);

}

} //名称空间ns

就这样!当json使用类型调用构造函数时,自定义to_json方法将被自动调用。同样,在调用get<your_type>()或时get_to(your_type&),from_json将调用该方法。

一些重要的事情:

  • 这些方法必须位于类型的名称空间(可以是全局名称空间)中,否则库将无法找到(在本示例中,位于定义的名称空间ns中person)。
  • 在使用这些转换的任何地方,这些方法都必须可用(例如,必须包含适当的标头)。请查看问题1108,了解否则可能发生的错误。
  • 使用时get<your_type>(),your_type 必须DefaultConstructible。(有一种绕过此要求的方法,将在后面介绍。)
  • 在函数中from_json,使用函数at()访问对象值而不是operator[]。万一键不存在,at将引发可以处理的异常,而operator[]表现出未定义的行为。
  • 无需为STL类型添加序列化器或反序列化器,例如std::vector:该库已经实现了这些。

使用宏简化生活

如果只想对一些结构进行序列化/反序列化,则to_json/ from_json函数可能会很多。

只要(1)想要将JSON对象用作序列化和(2)要将成员变量名称用作该对象中的对象键,就有两个宏可以使生活更轻松:

  • NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(name, member1, member2, ...) 将在要为其创建代码的类/结构的名称空间内定义。
  • NLOHMANN_DEFINE_TYPE_INTRUSIVE(name, member1, member2, ...)在要为其创建代码的类/结构中定义。该宏还可以访问私有成员。

在两个宏中,第一个参数是类/结构的名称,其余所有参数都为成员命名。

例子

上面结构的to_json/ from_json函数person可以通过以下方式创建:

命名空间 ns {

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(人,姓名,地址,年龄)

}

这是一个NLOHMANN_DEFINE_TYPE_INTRUSIVE需要私人成员的示例:

命名空间 ns {

类 地址 {

私有:

std :: string street;

INT housenumber;

INT邮编;

公开:

NLOHMANN_DEFINE_TYPE_INTRUSIVE(地址,街道,门牌号,邮政编码)

};

}

如何转换第三方类型?

这需要更高级的技术。但首先,让看看这种转换机制是如何工作的:

该库使用JSON序列化器将类型转换为json。默认的序列化器nlohmann::json为nlohmann::adl_serializer(ADL表示参数依赖查找)。

这样实现(简化):

template < typename T>

struct  adl_serializer {

static  void  to_json(json&j,const T&value){

//在T的命名空间中调用“ to_json”方法

}

static  void  from_json(const json&j,T&value){

//相同,但使用“ from_json”方法

}

};

当可以控制类型的名称空间时,此序列化程序可以正常工作。但是,关于boost::optional或std::filesystem::path(C ++ 17)呢?劫持boost名称空间是非常糟糕的,并且向模板添加模板专业化以外的内容是非法的std。

为了解决这个问题,需要adl_serializer在nlohmann名称空间中添加的特殊化,这是一个示例:

//部分专业化(也可以完全专业化)

名称空间 nlohmann {

模板 <类型名 T>

struct  adl_serializer <boost :: optional <T >> {

静态 void  to_json(json&j, const boost :: optional <T>&opt){

如果(opt == boost :: none){

j = nullptr ;

} 其 {

j = * opt; //这将调用adl_serializer <T> :: to_json将

//发现T的命名空间中的自由函数to_json!

}

}

静态 无效 from_json(const json&j,boost :: optional <T>&opt){

if(j。is_null()){

opt = boost :: none;

} 其 {

选择= j。得到 <T>(); //与上述相同,但

//使用 adl_serializer <T> :: from_json

}

}

};

}

如何get()用于非默认的可构造/不可复制类型?

如果类型为MoveConstructible,则有一种方法。还需要专门化adl_serializer,但要有一个特殊的from_json重载:

struct  move_only_type {

move_only_type()= 删除 ;

move_only_type(int ii):i(ii){}

move_only_type(const move_only_type&)= delete ;

move_only_type(move_only_type &&)= 默认值;

诠释 I;

};

名称空间 nlohmann {

template <>

struct  adl_serializer <move_only_type> {

//注意:返回类型不再是'void',该方法仅

//使用一个参数

static move_only_type from_json(const json&j){

return {j。get < int >()};

}

//这就是陷阱!必须提供to_json方法!否则

//

将//无法将move_only_type转换为json,因为完全//对该类型的adl_serializer进行了专门化//

static  void  to_json(json&j,move_only_type t){

j = t  ;

}

};

}

可以编写自己的序列化器吗?(高级使用)

是。可能需要看一下unit-udt.cpp测试套件,以查看一些示例。

如果编写自己的序列化器,则需要做一些事情:

  • 使用不同的basic_json别名nlohmann::json(的最后一个模板参数basic_json是JSONSerializer)
  • basic_json在所有to_json/ from_json方法中使用别名(或模板参数)
  • 使用nlohmann::to_json以及nlohmann::from_json何时需要ADL

这是一个示例,没有简化,仅接受大小<= 32的类型,并使用ADL。

// //应该使用void作为第二个模板参数

// //如果不需要对T

template < typename T, typename SFINAE = typename std :: enable_if < sizeof(T)<= 32 > :: type进行编译时检查 >

struct  less_than_32_serializer {

模板 <类型名称BasicJsonType>

静态 void  to_json(BasicJsonType&j,T值){

//要使用ADL,并

使用 nlohmann :: to_json调用正确的to_json重载;//这个方法由adl_serializer调用,

//这就是

to_json(j,value)发生魔术的地方;

}

template < typename BasicJsonType>

静态 无效 from_json(const BasicJsonType&j,T&value){

//

使用 nlohmann :: from_json进行相同操作;

from_json(j,值);

}

};

重新实现序列化器时要非常小心,如果不注意,可能会导致堆栈溢出:

模板 < 类型名 T,无效 >

结构 bad_serializer

{

template < typename BasicJsonType>

static  void  to_json(BasicJsonType&j,const T&value){

//这将调用BasicJsonType :: json_serializer <T> :: to_json(j,value);

//如果BasicJsonType :: json_serializer == bad_serializer ...糟糕!

j =值;

}

template < typename BasicJsonType>

static  void  to_json(const BasicJsonType&j,T&value){

//这将调用BasicJsonType :: json_serializer <T> :: from_json(j,value);

//如果BasicJsonType :: json_serializer == bad_serializer ...糟糕!

值= j。模板 获取 <T>(); //哎呀!

}

};

专门进行枚举转换

默认情况下,枚举值以整数形式序列化为JSON。在某些情况下,这可能会导致不良行为。如果在将数据序列化为JSON之后对枚举进行了修改或重新排序,则较晚的反序列化JSON数据可能是未定义的或与原始预期值不同的枚举值。

可以更精确地指定给定枚举如何映射到JSON和从JSON映射,如下所示:

//示例枚举类型声明

枚举 TaskState {

TS_STOPPED,

TS_RUNNING,

TS_COMPLETED,

TS_INVALID = -1,

};

//将TaskState值作为字符串

NLOHMANN_JSON_SERIALIZE_ENUM 映射到JSON(TaskState,{

{TS_INVALID,nullptr },

{TS_STOPPED,“已停止” },

{TS_RUNNING,“正在运行” },

{TS_COMPLETED,“已完成”),

})

的NLOHMANN_JSON_SERIALIZE_ENUM()宏声明一组to_json()/ from_json()功能型TaskState,同时避免重复和样板序列化代码。

用法:

//以字符串形式枚举JSON

json j = TS_STOPPED;

断言(j == “ stopped ”);

//枚举的json字符串

json j3 = “正在运行”;

断言(j3.get <TaskState>()== TS_RUNNING);

//要枚举的未定义json值(其中,上面的第一个地图项是默认值)

json jPi = 3.14 ;

断言(jPi.get <TaskState>()== TS_INVALID);

就像上面的任意类型转换一样

  • NLOHMANN_JSON_SERIALIZE_ENUM() 必须在枚举类型的名称空间(可以是全局名称空间)中声明,否则库将无法找到,并且将默认为整数序列化。
  • 使用转换的任何地方都必须可用(例如,必须包含适当的标题)。

其要点:

  • 使用时get<ENUM_TYPE>(),未定义的JSON值将默认为地图中指定的第一对。仔细选择该默认对。
  • 如果在地图中多次指定枚举或JSON值,则在与JSON进行相互转换时,将从地图顶部的第一个匹配项返回。

二进制格式(BSONCBORMessagePackUBJSON

尽管JSON是一种无处不在的数据格式,但不是一种非常紧凑的格式,适合通过网络进行数据交换。因此,该库支持  BSON(二进制JSON),CBOR(简明二进制对象表示形式),MessagePackUBJSON(通用二进制JSON规范),以将JSON值有效地编码为字节向量并对该向量进行解码。

//创建一个JSON值

json j = R“( {” compact“:true,” schema“:0} )” _json;

//序列化为BSON

std :: vector <std :: uint8_t > v_bson = json :: to_bson(j);

// 0x1B,0x00、0x00、0x00、0x08、0x63、0x6F,0x6D,0x70、0x61、0x63、0x74、0x00、0x01、0x10、0x73、0x63、0x68、0x65、0x6D,0x61、0x00、0x00 0x00、0x00、0x00

//往返

json j_from_bson = json :: from_bson(v_bson);

//序列化为CBOR

std :: vector <std :: uint8_t > v_cbor = json :: to_cbor(j);

// 0xA2、0x67、0x63、0x6F,0x6D,0x70、0x61、0x63、0x74、0xF5、0x66、0x73、0x63、0x68、0x65、0x6D,0x61、0x00

//往返

json j_from_cbor = json :: from_cbor(v_cbor);

//序列化为MessagePack

std :: vector <std :: uint8_t > v_msgpack = json :: to_msgpack(j);

// 0x82、0xA7、0x63、0x6F,0x6D,0x70、0x61、0x63、0x74、0xC3、0xA6、0x73、0x63、0x68、0x65、0x6D,0x61、0x00

//往返

json j_from_msgpack = json :: from_msgpack(v_msgpack);

//序列化为UBJSON

std :: vector <std :: uint8_t > v_ubjson = json :: to_ubjson(j);

// 0x7B,0x69、0x07、0x63、0x6F,0x6D,0x70、0x61、0x63、0x74、0x54、0x69、0x06、0x73、0x63、0x68、0x65、0x6D,0x61、0x69、0x00、0x7D

//往返

json j_from_ubjson = json :: from_ubjson(v_ubjson);

该库还支持BSON,CBOR(字节字符串)和MessagePack(bin,ext,fixext)的二进制类型。默认存储std::vector<std::uint8_t>为在库外部进行处理。

// CBOR字节串与有效载荷为0xCAFE

的std ::矢量<性病:: uint8_t > V = {的0x42, 0xCA, 0xFE的 };

//读取值

json j = json :: from_cbor(v);

// JSON值的类型为binary

j.is_binary(); //正确

//获取对存储的二进制值的引用

auto&binary = j.get_binary();

//二进制值没有子类型(CBOR没有二进制子类型)

binary.has_subtype(); //错误

//访问std :: vector <std :: uint8_t>成员函数

binary.size(); // 2

binary [ 0 ]; // 0xCA

binary [ 1 ]; // 0xFE

//将子类型设置为0x10

二进制。set_subtype( 0x10);

//序列化为MessagePack

auto cbor = json :: to_msgpack(j); // 0xD5(fixext2),0x10、0xCA,0xFE

支持的编译器

尽管已经是2020年,但对C ++ 11的支持仍然很少。当前,已知以下编译器可以工作:

  • GCC 4.8-10.1(可能以后)
  • 铛3.4-10.0(可能以后)
  • Apple Clang 9.1-12.0(可能更高)
  • 英特尔C ++编译器17.0.2(可能更高)
  • Microsoft Visual C ++ 2015 /构建工具14.0.25123.0(以及更高版本)
  • Microsoft Visual C ++ 2017 /生成工具15.5.180.51428(以及更高版本)
  • Microsoft Visual C ++ 2019 /生成工具16.3.1 + 1def00d3d(以及更高版本)

很乐意了解其编译器/版本。

请注意:

  • GCC 4.8有一个错误57824):多行原始字符串不能作为宏的参数。不要使用此编译器直接在宏中使用多行原始字符串。
  • Android默认使用非常老的编译器和C ++库。要解决此问题,请将以下内容添加到中Application.mk。这将切换到LLVM C ++库,Clang编译器,并启用C ++ 11和其默认禁用的功能。
  • APP_STL := c++_shared
  • NDK_TOOLCHAIN_VERSION := clang3.6
  • APP_CPPFLAGS += -frtti -fexceptions

该代码可使用Android NDK,修订版9-11(以及更高版本)和CrystaX的Android NDK版本10 成功编译。

  • 对于在MinGW或Android SDK上运行的GCC 'to_string' is not a member of 'std',可能会发生错误(或类似的for strtod或strtof)。注意,这不是代码问题,而是编译器本身的问题。在Android上,请参见上文以使用较新的环境进行构建。对于MinGW,请参考此站点此讨论以获取有关如何修复此错误的信息。对于Android NDK的使用APP_STL := gnustl_static,请参考此讨论
  • #error指令拒绝不支持的GCC和Clang版本。可以通过定义关闭JSON_SKIP_UNSUPPORTED_COMPILER_CHECK。请注意,在这种情况下,不希望获得任何支持。

TravisAppVeyorGitHub ActionsCircleCI当前在持续集成中使用编译器

Json文件解析(下)的更多相关文章

  1. Json文件解析(上)

    Json文件解析(上) 代码地址:https://github.com/nlohmann/json 自述文件 alt=GitHub赞助商 data-canonical-src="https: ...

  2. Golang Json文件解析为结构体工具-json2go

    代码地址如下:http://www.demodashi.com/demo/14946.html 概述 json2go是一个基于Golang开发的轻量json文件解析.转换命令行工具,目前支持转换输出到 ...

  3. PHP JSON文件解析并获取key、value,判断key是否存在

    /****************************************************************************** * PHP JSON文件解析并获取key ...

  4. 【微信】微信小程序 微信开发工具中新创建的json文件,编译报错VM1781:2 pages/module/module.json 文件解析错误 SyntaxError: Unexpected end of JSON input

    如果新创建报错:编译报错VM1781:2 pages/module/module.json 文件解析错误  SyntaxError: Unexpected end of JSON input 解决方法 ...

  5. NPOI+Json文件解析Excel

    记点笔记,加深印象!最近有个导入Excel工能需要完成,Excel列名是中文的,导入Excel我用的NPOI插件,如果不对Excel做解析,列名有可能会给我带来一些字符方面的麻烦,于是想到了一个比较l ...

  6. Twaver的mono-desiner导出的json文件解析

    以画的交换机为例,其他大概都差不多. 利用Twaver做出交换机模型如图1所示,其中,每一个端口都是一个单独的对象.具体Twaver操作流程参见网址:http://twaver.servasoft.c ...

  7. json 文件解析与应用

    第一步:首先弄一个 json 文件   我这里成为 config.json 内容如下 { ": { , "desc":"中华人民共和国" }, &qu ...

  8. vue之package.json文件解析

    1.package.json是什么? 什么是Node.js的模块(Module)?在Node.js中,模块是一个库或框架,也是一个Node.js项目.Node.js项目遵循模块化的架构,当我们创建了一 ...

  9. json文件解析

    场景 读取json文件,读取子域名扫描结果 实现 >>> import json >>> with open("C:\\Users\\Windows32\ ...

随机推荐

  1. Windows之磁盘管理

    0x01 磁盘管理概述 ​ 磁盘管理是一项计算机使用时的常规任务,它是以一组磁盘管理应用程序的形式提供给用户的,他们位于计算机管理控制台中,它包括查错程序和磁盘碎片整理程序以及磁盘整理程序.(来源百度 ...

  2. Python脚本爬取网站美女照片

    上次无意之中看到一个网站,里面全是美女的照片,我就心想,哪天有时间了得把这网站的所有美女照片都得爬下来.今天有时间,写了点代码,爬去了网站的所有照片.附上战果!图片实在是太多了,爬半个多小时 先附上所 ...

  3. UVA11549计算器谜题

    题意:        有一个计算机只能保留数字的前n位,你有一个数字k(k<=9),反复平方后在计算机上显示的最大数字是多少. 思路:       显然这个题目是有循环节的,为什么有循环节?首先 ...

  4. CTF密码学常见加解密总结

    CTF密码学常见加解密总结 2018年03月10日 19:35:06 adversity` 本文链接:https://blog.csdn.net/qq_40836553/article/details ...

  5. IO异步,读写压缩文件,监控文件系统

    这节结尾IO,讲一下异步操作文件,读写压缩文件,监控文件系统这三个知识点. 异步操作文件:     说到异步,必然要了解的是async和await这两个关键字(异步详情点击基于任务的异步编程(Task ...

  6. Python 之父爆料:明年至少令 Python 提速 1 倍!

    大概在半年前,我偶然看到一篇文章,有人提出了给 Python 提速 5 倍的计划,并在寻找经费赞助.当时并没有在意,此后也没有看到这方面的消息. 但是,就在 5 月 13 日"2021 年 ...

  7. Convert character array to string in MATLAB

    Matlab提取特征值是经常要读取多个图片文件,把文件名保存在数组中后再读取会出错.从stackoverflow中找到如下解决方法: I've a M by N matrix, each cell c ...

  8. 【BUAA软工】第一次团队作业——团队介绍

    项目 内容 班级:北航2020春软件工程 博客园班级博客 作业:团队介绍与采访往届团队 团队作业-团队介绍和采访 Part I 团队成员介绍 有图有真(jia)相 大名 个人介绍 角色意向 李PX 来 ...

  9. 每天一个linux命令(49):at命令   atrm删除作业,由作业号标识。

    atq命令 例如:从现在起三天后的下午四点运行作业at 4pm + 3 days:在July 31上午十点运行作业at 10am July 31:明天上午一点运行作业at 1am tomorrow. ...

  10. 030. Python装饰器

    一  装饰器 1.1 装饰器介绍 扩展函数新功能的@定义:替换旧函数,返回新函数,在不改变原有代码的前提下,为该函数扩展新功能;语法:@ (语法糖) 1.2 装饰器的原型 def show(func) ...