Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleOCR
提交
b8834933
P
PaddleOCR
项目概览
PaddlePaddle
/
PaddleOCR
大约 1 年 前同步成功
通知
1528
Star
32962
Fork
6643
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
108
列表
看板
标记
里程碑
合并请求
7
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleOCR
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
108
Issue
108
列表
看板
标记
里程碑
合并请求
7
合并请求
7
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
b8834933
编写于
6月 28, 2021
作者:
L
LDOUBLEV
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
delete benchmark
上级
bc999986
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
9 addition
and
223 deletion
+9
-223
tools/infer/predict_cls.py
tools/infer/predict_cls.py
+1
-13
tools/infer/predict_rec.py
tools/infer/predict_rec.py
+3
-48
tools/infer/predict_system.py
tools/infer/predict_system.py
+1
-62
tools/infer/utility.py
tools/infer/utility.py
+4
-100
未找到文件。
tools/infer/predict_cls.py
浏览文件 @
b8834933
...
@@ -48,8 +48,6 @@ class TextClassifier(object):
...
@@ -48,8 +48,6 @@ class TextClassifier(object):
self
.
predictor
,
self
.
input_tensor
,
self
.
output_tensors
,
_
=
\
self
.
predictor
,
self
.
input_tensor
,
self
.
output_tensors
,
_
=
\
utility
.
create_predictor
(
args
,
'cls'
,
logger
)
utility
.
create_predictor
(
args
,
'cls'
,
logger
)
self
.
cls_times
=
utility
.
Timer
()
def
resize_norm_img
(
self
,
img
):
def
resize_norm_img
(
self
,
img
):
imgC
,
imgH
,
imgW
=
self
.
cls_image_shape
imgC
,
imgH
,
imgW
=
self
.
cls_image_shape
h
=
img
.
shape
[
0
]
h
=
img
.
shape
[
0
]
...
@@ -85,35 +83,28 @@ class TextClassifier(object):
...
@@ -85,35 +83,28 @@ class TextClassifier(object):
cls_res
=
[[
''
,
0.0
]]
*
img_num
cls_res
=
[[
''
,
0.0
]]
*
img_num
batch_num
=
self
.
cls_batch_num
batch_num
=
self
.
cls_batch_num
elapse
=
0
elapse
=
0
self
.
cls_times
.
total_time
.
start
()
for
beg_img_no
in
range
(
0
,
img_num
,
batch_num
):
for
beg_img_no
in
range
(
0
,
img_num
,
batch_num
):
end_img_no
=
min
(
img_num
,
beg_img_no
+
batch_num
)
end_img_no
=
min
(
img_num
,
beg_img_no
+
batch_num
)
norm_img_batch
=
[]
norm_img_batch
=
[]
max_wh_ratio
=
0
max_wh_ratio
=
0
starttime
=
time
.
time
()
for
ino
in
range
(
beg_img_no
,
end_img_no
):
for
ino
in
range
(
beg_img_no
,
end_img_no
):
h
,
w
=
img_list
[
indices
[
ino
]].
shape
[
0
:
2
]
h
,
w
=
img_list
[
indices
[
ino
]].
shape
[
0
:
2
]
wh_ratio
=
w
*
1.0
/
h
wh_ratio
=
w
*
1.0
/
h
max_wh_ratio
=
max
(
max_wh_ratio
,
wh_ratio
)
max_wh_ratio
=
max
(
max_wh_ratio
,
wh_ratio
)
self
.
cls_times
.
preprocess_time
.
start
()
for
ino
in
range
(
beg_img_no
,
end_img_no
):
for
ino
in
range
(
beg_img_no
,
end_img_no
):
norm_img
=
self
.
resize_norm_img
(
img_list
[
indices
[
ino
]])
norm_img
=
self
.
resize_norm_img
(
img_list
[
indices
[
ino
]])
norm_img
=
norm_img
[
np
.
newaxis
,
:]
norm_img
=
norm_img
[
np
.
newaxis
,
:]
norm_img_batch
.
append
(
norm_img
)
norm_img_batch
.
append
(
norm_img
)
norm_img_batch
=
np
.
concatenate
(
norm_img_batch
)
norm_img_batch
=
np
.
concatenate
(
norm_img_batch
)
norm_img_batch
=
norm_img_batch
.
copy
()
norm_img_batch
=
norm_img_batch
.
copy
()
starttime
=
time
.
time
()
self
.
cls_times
.
preprocess_time
.
end
()
self
.
cls_times
.
inference_time
.
start
()
self
.
input_tensor
.
copy_from_cpu
(
norm_img_batch
)
self
.
input_tensor
.
copy_from_cpu
(
norm_img_batch
)
self
.
predictor
.
run
()
self
.
predictor
.
run
()
prob_out
=
self
.
output_tensors
[
0
].
copy_to_cpu
()
prob_out
=
self
.
output_tensors
[
0
].
copy_to_cpu
()
self
.
cls_times
.
inference_time
.
end
()
self
.
cls_times
.
postprocess_time
.
start
()
self
.
predictor
.
try_shrink_memory
()
self
.
predictor
.
try_shrink_memory
()
cls_result
=
self
.
postprocess_op
(
prob_out
)
cls_result
=
self
.
postprocess_op
(
prob_out
)
self
.
cls_times
.
postprocess_time
.
end
()
elapse
+=
time
.
time
()
-
starttime
elapse
+=
time
.
time
()
-
starttime
for
rno
in
range
(
len
(
cls_result
)):
for
rno
in
range
(
len
(
cls_result
)):
label
,
score
=
cls_result
[
rno
]
label
,
score
=
cls_result
[
rno
]
...
@@ -121,9 +112,6 @@ class TextClassifier(object):
...
@@ -121,9 +112,6 @@ class TextClassifier(object):
if
'180'
in
label
and
score
>
self
.
cls_thresh
:
if
'180'
in
label
and
score
>
self
.
cls_thresh
:
img_list
[
indices
[
beg_img_no
+
rno
]]
=
cv2
.
rotate
(
img_list
[
indices
[
beg_img_no
+
rno
]]
=
cv2
.
rotate
(
img_list
[
indices
[
beg_img_no
+
rno
]],
1
)
img_list
[
indices
[
beg_img_no
+
rno
]],
1
)
self
.
cls_times
.
total_time
.
end
()
self
.
cls_times
.
img_num
+=
img_num
elapse
=
self
.
cls_times
.
total_time
.
value
()
return
img_list
,
cls_res
,
elapse
return
img_list
,
cls_res
,
elapse
...
...
tools/infer/predict_rec.py
浏览文件 @
b8834933
...
@@ -66,8 +66,6 @@ class TextRecognizer(object):
...
@@ -66,8 +66,6 @@ class TextRecognizer(object):
self
.
predictor
,
self
.
input_tensor
,
self
.
output_tensors
,
self
.
config
=
\
self
.
predictor
,
self
.
input_tensor
,
self
.
output_tensors
,
self
.
config
=
\
utility
.
create_predictor
(
args
,
'rec'
,
logger
)
utility
.
create_predictor
(
args
,
'rec'
,
logger
)
self
.
rec_times
=
utility
.
Timer
()
def
resize_norm_img
(
self
,
img
,
max_wh_ratio
):
def
resize_norm_img
(
self
,
img
,
max_wh_ratio
):
imgC
,
imgH
,
imgW
=
self
.
rec_image_shape
imgC
,
imgH
,
imgW
=
self
.
rec_image_shape
assert
imgC
==
img
.
shape
[
2
]
assert
imgC
==
img
.
shape
[
2
]
...
@@ -168,14 +166,13 @@ class TextRecognizer(object):
...
@@ -168,14 +166,13 @@ class TextRecognizer(object):
width_list
.
append
(
img
.
shape
[
1
]
/
float
(
img
.
shape
[
0
]))
width_list
.
append
(
img
.
shape
[
1
]
/
float
(
img
.
shape
[
0
]))
# Sorting can speed up the recognition process
# Sorting can speed up the recognition process
indices
=
np
.
argsort
(
np
.
array
(
width_list
))
indices
=
np
.
argsort
(
np
.
array
(
width_list
))
self
.
rec_times
.
total_time
.
start
()
rec_res
=
[[
''
,
0.0
]]
*
img_num
rec_res
=
[[
''
,
0.0
]]
*
img_num
batch_num
=
self
.
rec_batch_num
batch_num
=
self
.
rec_batch_num
st
=
time
.
time
()
for
beg_img_no
in
range
(
0
,
img_num
,
batch_num
):
for
beg_img_no
in
range
(
0
,
img_num
,
batch_num
):
end_img_no
=
min
(
img_num
,
beg_img_no
+
batch_num
)
end_img_no
=
min
(
img_num
,
beg_img_no
+
batch_num
)
norm_img_batch
=
[]
norm_img_batch
=
[]
max_wh_ratio
=
0
max_wh_ratio
=
0
self
.
rec_times
.
preprocess_time
.
start
()
for
ino
in
range
(
beg_img_no
,
end_img_no
):
for
ino
in
range
(
beg_img_no
,
end_img_no
):
h
,
w
=
img_list
[
indices
[
ino
]].
shape
[
0
:
2
]
h
,
w
=
img_list
[
indices
[
ino
]].
shape
[
0
:
2
]
wh_ratio
=
w
*
1.0
/
h
wh_ratio
=
w
*
1.0
/
h
...
@@ -216,8 +213,6 @@ class TextRecognizer(object):
...
@@ -216,8 +213,6 @@ class TextRecognizer(object):
gsrm_slf_attn_bias1_list
,
gsrm_slf_attn_bias1_list
,
gsrm_slf_attn_bias2_list
,
gsrm_slf_attn_bias2_list
,
]
]
self
.
rec_times
.
preprocess_time
.
end
()
self
.
rec_times
.
inference_time
.
start
()
input_names
=
self
.
predictor
.
get_input_names
()
input_names
=
self
.
predictor
.
get_input_names
()
for
i
in
range
(
len
(
input_names
)):
for
i
in
range
(
len
(
input_names
)):
input_tensor
=
self
.
predictor
.
get_input_handle
(
input_names
[
input_tensor
=
self
.
predictor
.
get_input_handle
(
input_names
[
...
@@ -241,15 +236,13 @@ class TextRecognizer(object):
...
@@ -241,15 +236,13 @@ class TextRecognizer(object):
output
=
output_tensor
.
copy_to_cpu
()
output
=
output_tensor
.
copy_to_cpu
()
outputs
.
append
(
output
)
outputs
.
append
(
output
)
preds
=
outputs
[
0
]
preds
=
outputs
[
0
]
self
.
rec_times
.
inference_time
.
end
()
self
.
rec_times
.
postprocess_time
.
start
()
rec_result
=
self
.
postprocess_op
(
preds
)
rec_result
=
self
.
postprocess_op
(
preds
)
for
rno
in
range
(
len
(
rec_result
)):
for
rno
in
range
(
len
(
rec_result
)):
rec_res
[
indices
[
beg_img_no
+
rno
]]
=
rec_result
[
rno
]
rec_res
[
indices
[
beg_img_no
+
rno
]]
=
rec_result
[
rno
]
self
.
rec_times
.
postprocess_time
.
end
()
self
.
rec_times
.
postprocess_time
.
end
()
self
.
rec_times
.
img_num
+=
int
(
norm_img_batch
.
shape
[
0
])
self
.
rec_times
.
img_num
+=
int
(
norm_img_batch
.
shape
[
0
])
self
.
rec_times
.
total_time
.
end
()
return
rec_res
,
self
.
rec_times
.
total_time
.
value
()
return
rec_res
,
time
.
time
()
-
st
def
main
(
args
):
def
main
(
args
):
...
@@ -278,12 +271,6 @@ def main(args):
...
@@ -278,12 +271,6 @@ def main(args):
img_list
.
append
(
img
)
img_list
.
append
(
img
)
try
:
try
:
rec_res
,
_
=
text_recognizer
(
img_list
)
rec_res
,
_
=
text_recognizer
(
img_list
)
if
args
.
benchmark
:
cm
,
gm
,
gu
=
utility
.
get_current_memory_mb
(
0
)
cpu_mem
+=
cm
gpu_mem
+=
gm
gpu_util
+=
gu
count
+=
1
except
Exception
as
E
:
except
Exception
as
E
:
logger
.
info
(
traceback
.
format_exc
())
logger
.
info
(
traceback
.
format_exc
())
...
@@ -292,38 +279,6 @@ def main(args):
...
@@ -292,38 +279,6 @@ def main(args):
for
ino
in
range
(
len
(
img_list
)):
for
ino
in
range
(
len
(
img_list
)):
logger
.
info
(
"Predicts of {}:{}"
.
format
(
valid_image_file_list
[
ino
],
logger
.
info
(
"Predicts of {}:{}"
.
format
(
valid_image_file_list
[
ino
],
rec_res
[
ino
]))
rec_res
[
ino
]))
if
args
.
benchmark
:
mems
=
{
'cpu_rss_mb'
:
cpu_mem
/
count
,
'gpu_rss_mb'
:
gpu_mem
/
count
,
'gpu_util'
:
gpu_util
*
100
/
count
}
else
:
mems
=
None
logger
.
info
(
"The predict time about recognizer module is as follows: "
)
rec_time_dict
=
text_recognizer
.
rec_times
.
report
(
average
=
True
)
rec_model_name
=
args
.
rec_model_dir
if
args
.
benchmark
:
# construct log information
model_info
=
{
'model_name'
:
args
.
rec_model_dir
.
split
(
'/'
)[
-
1
],
'precision'
:
args
.
precision
}
data_info
=
{
'batch_size'
:
args
.
rec_batch_num
,
'shape'
:
'dynamic_shape'
,
'data_num'
:
rec_time_dict
[
'img_num'
]
}
perf_info
=
{
'preprocess_time_s'
:
rec_time_dict
[
'preprocess_time'
],
'inference_time_s'
:
rec_time_dict
[
'inference_time'
],
'postprocess_time_s'
:
rec_time_dict
[
'postprocess_time'
],
'total_time_s'
:
rec_time_dict
[
'total_time'
]
}
benchmark_log
=
benchmark_utils
.
PaddleInferBenchmark
(
text_recognizer
.
config
,
model_info
,
data_info
,
perf_info
,
mems
)
benchmark_log
(
"Rec"
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
...
...
tools/infer/predict_system.py
浏览文件 @
b8834933
...
@@ -175,12 +175,6 @@ def main(args):
...
@@ -175,12 +175,6 @@ def main(args):
dt_boxes
,
rec_res
=
text_sys
(
img
)
dt_boxes
,
rec_res
=
text_sys
(
img
)
elapse
=
time
.
time
()
-
starttime
elapse
=
time
.
time
()
-
starttime
total_time
+=
elapse
total_time
+=
elapse
if
args
.
benchmark
and
idx
%
20
==
0
:
cm
,
gm
,
gu
=
get_current_memory_mb
(
0
)
cpu_mem
+=
cm
gpu_mem
+=
gm
gpu_util
+=
gu
count
+=
1
logger
.
info
(
logger
.
info
(
str
(
idx
)
+
" Predict time of %s: %.3fs"
%
(
image_file
,
elapse
))
str
(
idx
)
+
" Predict time of %s: %.3fs"
%
(
image_file
,
elapse
))
...
@@ -215,61 +209,6 @@ def main(args):
...
@@ -215,61 +209,6 @@ def main(args):
logger
.
info
(
"
\n
The predict total time is {}"
.
format
(
total_time
))
logger
.
info
(
"
\n
The predict total time is {}"
.
format
(
total_time
))
img_num
=
text_sys
.
text_detector
.
det_times
.
img_num
img_num
=
text_sys
.
text_detector
.
det_times
.
img_num
if
args
.
benchmark
:
mems
=
{
'cpu_rss_mb'
:
cpu_mem
/
count
,
'gpu_rss_mb'
:
gpu_mem
/
count
,
'gpu_util'
:
gpu_util
*
100
/
count
}
else
:
mems
=
None
det_time_dict
=
text_sys
.
text_detector
.
det_times
.
report
(
average
=
True
)
rec_time_dict
=
text_sys
.
text_recognizer
.
rec_times
.
report
(
average
=
True
)
det_model_name
=
args
.
det_model_dir
rec_model_name
=
args
.
rec_model_dir
# construct det log information
model_info
=
{
'model_name'
:
args
.
det_model_dir
.
split
(
'/'
)[
-
1
],
'precision'
:
args
.
precision
}
data_info
=
{
'batch_size'
:
1
,
'shape'
:
'dynamic_shape'
,
'data_num'
:
det_time_dict
[
'img_num'
]
}
perf_info
=
{
'preprocess_time_s'
:
det_time_dict
[
'preprocess_time'
],
'inference_time_s'
:
det_time_dict
[
'inference_time'
],
'postprocess_time_s'
:
det_time_dict
[
'postprocess_time'
],
'total_time_s'
:
det_time_dict
[
'total_time'
]
}
benchmark_log
=
benchmark_utils
.
PaddleInferBenchmark
(
text_sys
.
text_detector
.
config
,
model_info
,
data_info
,
perf_info
,
mems
,
args
.
save_log_path
)
benchmark_log
(
"Det"
)
# construct rec log information
model_info
=
{
'model_name'
:
args
.
rec_model_dir
.
split
(
'/'
)[
-
1
],
'precision'
:
args
.
precision
}
data_info
=
{
'batch_size'
:
args
.
rec_batch_num
,
'shape'
:
'dynamic_shape'
,
'data_num'
:
rec_time_dict
[
'img_num'
]
}
perf_info
=
{
'preprocess_time_s'
:
rec_time_dict
[
'preprocess_time'
],
'inference_time_s'
:
rec_time_dict
[
'inference_time'
],
'postprocess_time_s'
:
rec_time_dict
[
'postprocess_time'
],
'total_time_s'
:
rec_time_dict
[
'total_time'
]
}
benchmark_log
=
benchmark_utils
.
PaddleInferBenchmark
(
text_sys
.
text_recognizer
.
config
,
model_info
,
data_info
,
perf_info
,
mems
,
args
.
save_log_path
)
benchmark_log
(
"Rec"
)
if
__name__
==
"__main__"
:
if
__name__
==
"__main__"
:
...
...
tools/infer/utility.py
浏览文件 @
b8834933
...
@@ -124,76 +124,6 @@ def parse_args():
...
@@ -124,76 +124,6 @@ def parse_args():
return
parser
.
parse_args
()
return
parser
.
parse_args
()
class
Times
(
object
):
def
__init__
(
self
):
self
.
time
=
0.
self
.
st
=
0.
self
.
et
=
0.
def
start
(
self
):
self
.
st
=
time
.
time
()
def
end
(
self
,
accumulative
=
True
):
self
.
et
=
time
.
time
()
if
accumulative
:
self
.
time
+=
self
.
et
-
self
.
st
else
:
self
.
time
=
self
.
et
-
self
.
st
def
reset
(
self
):
self
.
time
=
0.
self
.
st
=
0.
self
.
et
=
0.
def
value
(
self
):
return
round
(
self
.
time
,
4
)
class
Timer
(
Times
):
def
__init__
(
self
):
super
(
Timer
,
self
).
__init__
()
self
.
total_time
=
Times
()
self
.
preprocess_time
=
Times
()
self
.
inference_time
=
Times
()
self
.
postprocess_time
=
Times
()
self
.
img_num
=
0
def
info
(
self
,
average
=
False
):
logger
.
info
(
"----------------------- Perf info -----------------------"
)
logger
.
info
(
"total_time: {}, img_num: {}"
.
format
(
self
.
total_time
.
value
(
),
self
.
img_num
))
preprocess_time
=
round
(
self
.
preprocess_time
.
value
()
/
self
.
img_num
,
4
)
if
average
else
self
.
preprocess_time
.
value
()
postprocess_time
=
round
(
self
.
postprocess_time
.
value
()
/
self
.
img_num
,
4
)
if
average
else
self
.
postprocess_time
.
value
()
inference_time
=
round
(
self
.
inference_time
.
value
()
/
self
.
img_num
,
4
)
if
average
else
self
.
inference_time
.
value
()
average_latency
=
self
.
total_time
.
value
()
/
self
.
img_num
logger
.
info
(
"average_latency(ms): {:.2f}, QPS: {:2f}"
.
format
(
average_latency
*
1000
,
1
/
average_latency
))
logger
.
info
(
"preprocess_latency(ms): {:.2f}, inference_latency(ms): {:.2f}, postprocess_latency(ms): {:.2f}"
.
format
(
preprocess_time
*
1000
,
inference_time
*
1000
,
postprocess_time
*
1000
))
def
report
(
self
,
average
=
False
):
dic
=
{}
dic
[
'preprocess_time'
]
=
round
(
self
.
preprocess_time
.
value
()
/
self
.
img_num
,
4
)
if
average
else
self
.
preprocess_time
.
value
()
dic
[
'postprocess_time'
]
=
round
(
self
.
postprocess_time
.
value
()
/
self
.
img_num
,
4
)
if
average
else
self
.
postprocess_time
.
value
()
dic
[
'inference_time'
]
=
round
(
self
.
inference_time
.
value
()
/
self
.
img_num
,
4
)
if
average
else
self
.
inference_time
.
value
()
dic
[
'img_num'
]
=
self
.
img_num
dic
[
'total_time'
]
=
round
(
self
.
total_time
.
value
(),
4
)
return
dic
def
create_predictor
(
args
,
mode
,
logger
):
def
create_predictor
(
args
,
mode
,
logger
):
if
mode
==
"det"
:
if
mode
==
"det"
:
model_dir
=
args
.
det_model_dir
model_dir
=
args
.
det_model_dir
...
@@ -212,11 +142,10 @@ def create_predictor(args, mode, logger):
...
@@ -212,11 +142,10 @@ def create_predictor(args, mode, logger):
model_file_path
=
model_dir
+
"/inference.pdmodel"
model_file_path
=
model_dir
+
"/inference.pdmodel"
params_file_path
=
model_dir
+
"/inference.pdiparams"
params_file_path
=
model_dir
+
"/inference.pdiparams"
if
not
os
.
path
.
exists
(
model_file_path
):
if
not
os
.
path
.
exists
(
model_file_path
):
logger
.
info
(
"not find model file path {}"
.
format
(
model_file_path
))
raise
ValueError
(
"not find model file path {}"
.
format
(
model_file_path
))
sys
.
exit
(
0
)
if
not
os
.
path
.
exists
(
params_file_path
):
if
not
os
.
path
.
exists
(
params_file_path
):
logger
.
info
(
"not find params file path {}"
.
format
(
params_file_path
))
raise
ValueError
(
"not find params file path {}"
.
format
(
sys
.
exit
(
0
)
params_file_path
)
)
config
=
inference
.
Config
(
model_file_path
,
params_file_path
)
config
=
inference
.
Config
(
model_file_path
,
params_file_path
)
...
@@ -597,30 +526,5 @@ def draw_boxes(image, boxes, scores=None, drop_score=0.5):
...
@@ -597,30 +526,5 @@ def draw_boxes(image, boxes, scores=None, drop_score=0.5):
return
image
return
image
def
get_current_memory_mb
(
gpu_id
=
None
):
"""
It is used to Obtain the memory usage of the CPU and GPU during the running of the program.
And this function Current program is time-consuming.
"""
import
pynvml
import
psutil
import
GPUtil
pid
=
os
.
getpid
()
p
=
psutil
.
Process
(
pid
)
info
=
p
.
memory_full_info
()
cpu_mem
=
info
.
uss
/
1024.
/
1024.
gpu_mem
=
0
gpu_percent
=
0
if
gpu_id
is
not
None
:
GPUs
=
GPUtil
.
getGPUs
()
gpu_load
=
GPUs
[
gpu_id
].
load
gpu_percent
=
gpu_load
pynvml
.
nvmlInit
()
handle
=
pynvml
.
nvmlDeviceGetHandleByIndex
(
0
)
meminfo
=
pynvml
.
nvmlDeviceGetMemoryInfo
(
handle
)
gpu_mem
=
meminfo
.
used
/
1024.
/
1024.
return
round
(
cpu_mem
,
4
),
round
(
gpu_mem
,
4
),
round
(
gpu_percent
,
4
)
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
pass
pass
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录