• [技术干货] Python学习之configparser模块的使用详解【转】
    ConfigParser是用来读取配置文件的包。这篇文章主要通过一些简单的实例带大家了解一下ConfigParser模块的具体使用,感兴趣的小伙伴跟随小编一起了解一下+目录1 configparser安装1pip3 install configparser2 configparser简介用来读取配置文件的python包;一般做自动化测试的时候,会使用到这个模块,用来封装一些常量。比如数据库、邮件、用户名密码、项目常量等等;这个使用根据个人喜好和项目来确定,不一定一定要使用这个模块,也可以使用其它的方法做配置,比如py文件、xml、excel、yaml、json等等。configparser源码大约1360行左右,通读源码可有效了解该模块的使用。本文只做简单介绍常用的方法。3 表示方法新建一个名为conf.py文件;写入如下数据,格式如下: [mysqldb] sql_host = 127.0.0.1 sql_port = 3699 sql_user = root sql_pass = 123456  [mailinfo] name = NoamaNelson passwd = 123456 address = 123456@qq.com 4 configparser详细使用4.1 对象初始化写入如下代码,把对象初始化。 # -*- coding:utf-8 -*- # 作者:NoamaNelson # 日期:2021/11/19  # 文件名称:conf.py # 作用:configparser模块的使用 # 联系:VX(NoamaNelson) # 博客:https://blog.csdn.net/NoamaNelson  import configparser import os  class Conf:     def __init__(self):         self.conf = configparser.ConfigParser()         self.root_path = os.path.dirname(os.path.abspath(__file__))         self.f = os.path.join(self.root_path + "/config.conf")         self.conf.read(self.f) 4.2 获取所有的sections def read_sections(self):         print(f"1、获取所有的sections:{self.conf.sections()}")  if __name__ == "__main__":     aa = Conf()     aa.read_sections() 结果为:D:\Python37\python.exe F:/python_study/conf.py1、获取所有的sections:['mysqldb', 'mailinfo']4.3 获取所有的sections对应的options def read_options(self, s1, s2):         print(f"2、获取mysqldb所有的options:{self.conf.options(s1)}")         print(f"3、获取mailinfo所有的options:{self.conf.options(s2)}")  if __name__ == "__main__":     aa = Conf()     aa.read_sections()     aa.read_options("mysqldb", "mailinfo") 结果为:D:\Python37\python.exe F:/python_study/conf.py1、获取所有的sections:['mysqldb', 'mailinfo']2、获取mysqldb所有的options:['sql_host', 'sql_port', 'sql_user', 'sql_pass']3、获取mailinfo所有的options:['name', 'passwd', 'address']4.4 read方法和get方法,获取指定section下的option值read是读取配置文件,如 self.conf.read(self.f)是读取指定config.conf文件;get是获取具体的值; def read_conf(self, m, n):         name = self.conf.get(m, n)  # 获取指定section的option值         print(f"4、获取指定section:{m}下的option:{n}的值为{name}")  if __name__ == "__main__":     aa = Conf()     aa.read_sections()     aa.read_options("mysqldb", "mailinfo")     aa.read_conf("mysqldb", "sql_host") 结果为:D:\Python37\python.exe F:/python_study/conf.py1、获取所有的sections:['mysqldb', 'mailinfo']2、获取mysqldb所有的options:['sql_host', 'sql_port', 'sql_user', 'sql_pass']3、获取mailinfo所有的options:['name', 'passwd', 'address']4、获取指定section:mysqldb下的option:sql_host的值为127.0.0.14.5 items方法,获取指点section所用配置信息 def get_items(self, m, n):         print(f"5、获取sectoion:{m}下的配置信息为:{self.conf.items(m)}")         print(f"6、获取sectoion:{n}下的配置信息为:{self.conf.items(n)}")  if __name__ == "__main__":     aa = Conf()     aa.read_sections()     aa.read_options("mysqldb", "mailinfo")     aa.read_conf("mysqldb", "sql_host")     aa.get_items("mysqldb", "mailinfo") 结果为:D:\Python37\python.exe F:/python_study/conf.py1、获取所有的sections:['mysqldb', 'mailinfo']2、获取mysqldb所有的options:['sql_host', 'sql_port', 'sql_user', 'sql_pass']3、获取mailinfo所有的options:['name', 'passwd', 'address']4、获取指定section:mysqldb下的option:sql_host的值为127.0.0.15、获取sectoion:mysqldb下的配置信息为:[('sql_host', '127.0.0.1'), ('sql_port', '3699'), ('sql_user', 'root'), ('sql_pass', '123456')]6、获取sectoion:mailinfo下的配置信息为:[('name', 'NoamaNelson'), ('passwd', '123456'), ('address', '123456@qq.com')]4.6 set和write方法,修改某个option的值如果option不存在则创建它; def set_option(self, m, n, s):         self.conf.set(m, n, s)         self.conf.write(open(self.f, "w"))         print(f"7、设置setion:{m}下的option:{n}的值为:{s}")  if __name__ == "__main__":     aa = Conf()     aa.read_sections()     aa.read_options("mysqldb", "mailinfo")     aa.read_conf("mysqldb", "sql_host")     aa.get_items("mysqldb", "mailinfo")     aa.set_option("mysqldb", "sql_name", "游客") 结果为:D:\Python37\python.exe F:/python_study/conf.py1、获取所有的sections:['mysqldb', 'mailinfo']2、获取mysqldb所有的options:['sql_host', 'sql_port', 'sql_user', 'sql_pass']3、获取mailinfo所有的options:['name', 'passwd', 'address']4、获取指定section:mysqldb下的option:sql_host的值为127.0.0.15、获取sectoion:mysqldb下的配置信息为:[('sql_host', '127.0.0.1'), ('sql_port', '3699'), ('sql_user', 'root'), ('sql_pass', '123456')]6、获取sectoion:mailinfo下的配置信息为:[('name', 'NoamaNelson'), ('passwd', '123456'), ('address', '123456@qq.com')]7、设置setion:mysqldb下的option:sql_name的值为:游客因为之前的配置文件中没有sql_name,所以会新创建它,如果创建的内容存在,直接修改对应的值; has_section和has_option方法has_section方法检查对应的section是否存在;has_option方法检查对应的option是否存在; def has_s_o(self, s, o):         print(f"8、检查section:{s}是否存在:{self.conf.has_section(s)}")         print(f"9、检查section:{s}下的option:{o}是否存在:{self.conf.has_option(s, o)}")  if __name__ == "__main__":     aa = Conf()     aa.read_sections()     aa.read_options("mysqldb", "mailinfo")     aa.read_conf("mysqldb", "sql_host")     aa.get_items("mysqldb", "mailinfo")     aa.set_option("mysqldb", "sql_name", "游客")     aa.has_s_o("mysqldb", "sql_name") 
  • [技术干货] Python实现内存泄露排查的示例详解【转】
    一般在python代码块的调试过程中会使用memory-profiler、filprofiler、objgraph等三种方式进行辅助分析,今天这里主要介绍使用objgraph对象提供的函数接口来进行内存泄露的分析,感兴趣的可以了解一下一般情况下只有需要长期运行的项目才会去关注内存的增长情况,即使是很小部分的内存泄露经过长期的运行仍然会产生很大的隐患。python本身也是支持垃圾的自动回收的,但是在特定的情况下也是会出现内存泄露的问题的。比如对于很多全局的列表(list)/字典(dict)等对象在经过不断的数据赋值而没有进行手动回收,或者某些对象被不停的循环引用而不能及时的进行回收等都会产生内存泄露的情况。一般在python代码块的调试过程中会使用memory-profiler、filprofiler、objgraph等三种方式进行辅助分析,今天这里主要介绍使用objgraph对象提供的函数接口来进行内存泄露的分析。objgraph是python的非标准模块,因此需要使用pip的方式安装一下。pip install objgraph 接下来就可以直接将objgraph导入到我们的代码块中进行使用了。# Importing the objgraph module and renaming it to graph. import objgraph as graph 这里初始化一组字典类型的数据对象。dict_ = {     '姓名': ['Python', 'Java', 'Scala'],     '年龄': ['21', '22', '19'] } 通过objgraph.count()函数,可以统计出GC中的dict_对象的数目是多少。# Counting the number of dict_ objects in the GC. print(graph.count(dict_)) 和objgraph.count()函数对应的是可以使用by_type返回该对象在GC中的列表,若是GC返回的为空的列表说明已经被回收了。# Returning a list of dict_ objects in the GC. print(graph.by_type(dict_)) 在统计内存泄露时比较好用的函数就是graph.show_growth()函数,可以统计自上次调用以来增加得最多的对象。 # Showing the growth of objects in the memory since the last time it was called. print(graph.show_growth())  # function                       3013     +3013 # tuple                          1463     +1463 # dict                           1417     +1417 # wrapper_descriptor             1178     +1178 # ReferenceType                   883      +883 # method_descriptor               814      +814 # builtin_function_or_method      794      +794 # getset_descriptor               514      +514 # type                            463      +463 # list                            436      +436 # None 可以根据返回结果中的对象每次增加的数量来判断内存泄露的相关情况。还有一个比较常用的分析函数就是graph.show_most_common_types(),可以按照从大到小的方式列出对象实例比较多的情况。 # Showing the most common types of objects in the memory. print(graph.show_most_common_types())  # function                   3013 # tuple                      1463 # dict                       1417 # wrapper_descriptor         1178 # ReferenceType              883 # method_descriptor          814 # builtin_function_or_method 794 # getset_descriptor          514 # type                       463 # list                       436 # None 最后一个比较使用函数就是show_backrefs函数,使用它可以分析出内存泄露的原因是什么。它会生成一张有关objs的引用图,可以看出对象为什么不释放?只是调用该函数时的参数比较多,下面是该函数的接口。# def show_backrefs(objs, max_depth=3, extra_ignore=(), filter=None, too_many=10, #                   highlight=None, filename=None, extra_info=None, #                   refcounts=False, shortnames=True, output=None, #                   extra_node_attrs=None): 我们还是和上面一样使用dict_作为对象进行分析。# Showing the back references of the dict_ object. graph.show_backrefs(dict_) 执行完成后dot类型的图片已经生成了,发现出现了下面的错误,意思是没有发现支持dot的图像组件。# Graph written to C:\Users\86159\AppData\Local\Temp\objgraph-dkqm85f0.dot (4 nodes) # Graph viewer (xdot) and image renderer (dot) not found, not doing anything else 可以使用pip的方式分别安装graphviz xdot,这两个python的非标准模块。pip install graphviz xdot 
  • [技术干货] python如何在pygame中设置字体并显示中文详解【转】
    一、查看可用字体import pygame print(pygame.font.get_fonts()) 二、设置字体1.使用系统字体self.font=pygame.font.SysFont(None,48)#None系统默认字体 self.font = pygame.font.SysFont("arial", 16) 2.使用字体文件字体文件可以外下载self.font = pygame.font.Font("my_font.ttf", 16) #字体,字号         3.设置中文()见前2#系统自带 self.font = pygame.font.SysFont("SimHei", 32)  # 显示中文在网上下载一个中文字体文件,将这个文件与我们的程序放在同一个文件夹,如果是中文的文件名,将它改成英文文件名。例如,下载了迷你简毡笔黑.TTF,将文件名改成了mnjzbh.ttf,并将程序的第一句改成:self.font=pygame.font.Font('mnjzbh.ttf',32) # 显示中文三、附录:常见系统字体对照表一般的中文字体名,使用拼音即可,如 仿宋fangsong, 楷体kaiti新细明体:PMingLiU细明体:MingLiU标楷体:DFKai-SB黑体:SimHei宋体:SimSun新宋体:NSimSun仿宋:FangSong楷体:KaiTi仿宋_GB2312:FangSong_GB2312楷体_GB2312:KaiTi_GB2312微软正黑体:Microsoft JhengHei微软雅黑体:Microsoft YaHei一个应用小例子 import pygame.font  class BUtton:     def __init__(self, ai_game, msg):         """初始化按钮属性"""         # msg是要在按钮上显示的文本         self.screen = ai_game.screen         self.screen_rect = ai_game.screen.get_rect()          # 设置按钮的尺寸和其他属性         self.width, self.height = 200, 50         self.buttom_color=(0,255,0)         self.text_color=(255,255,255)         self.font=pygame.font.SysFont(None,48)          #创建按钮的rect对象,并使其居中         self.rect=pygame.Rect(0,0,self.width,self.height)         self.rect.center=self.screen_rect.center          #按钮的标签只创建一次         self._pre_msg(msg)      def _pre_msg(self,msg):         """将msg渲染为图像,并使其在按钮上居中"""         self.msg_image=self.font.render(msg,True,self.text_color                                         ,self.buttom_color)         #布尔实参指定开启还是关闭反锯齿功能,反锯齿让文本的边缘更平滑         self.msg_image_rect=self.msg_image.get_rect()         #让图像文本在按钮上居中         self.msg_image_rect.center=self.rect.center      def draw_button(self):         """绘制一个用颜色填充的按钮,再绘制文本"""         self.screen.fill(self.buttom_color,self.rect)         self.screen.blit(self.msg_image,self.msg_image_rect) 
  • [技术干货] 一文详解pygame.sprite的精灵碰撞【转】
    精灵其实在一个游戏程序中,精灵本质指的是一张张小尺寸的图片,比如游戏中的各种道具、人物、场景装饰等,它们都可以看做成一张张小的“精灵”图,下面这篇文章主要给大家介绍了关于pygame.sprite精灵碰撞的相关资料,需要的朋友可以参考下+目录前言pygame中的精灵碰撞是可见游戏中用的最基础的东西,这里结合官方文档和小甲鱼的网站上的内容做个小总结,方便日后使用。pygame.sprite.Sprite - 可见游戏对象的简单基类。Sprite(*groups) -> Spritepygame.sprite.Sprite.add - 将精灵添加到组中pygame.sprite.Sprite.remove - 从组中删除精灵pygame.sprite.Sprite.kill - 从所有组中删除Spritepygame.sprite.Sprite.alive - 精灵属于任何组的检测pygame.sprite.Sprite.groups - 包含此Sprite的组列表pygame.sprite.Sprite.update - 控制精灵行为的方法pygame.sprite.Group - 用于保存和管理多个 Sprite 对象的容器类。Group(*sprites) -> Grouppygame.sprite.Group.sprites - 此组包含的 Sprite 列表pygame.sprite.Group.copy - 复制组pygame.sprite.Group.add - 将 Sprite 添加到此组pygame.sprite.Group.remove - 从组中删除 Spritepygame.sprite.Group.has - 测试一个 Group 是否包含 Spritepygame.sprite.Group.update - 在包含的 Sprite 上调用 update 方法pygame.sprite.Group.draw - blit Sprite 的图像pygame.sprite.Group.clear - 在 Sprites 上绘制背景pygame.sprite.Group.empty - 删除所有 Sprite`上面两个基类是pygame中最常用,相当轻量级,只为大多数游戏常见的代码提供了一个起始点。Sprite 类旨在用作游戏中不同类型对象的基类,为我们碰撞检测做准备。还有一个基本的 Group 类,它只存储 sprite 对象, 这样方便不同类型的精灵进行碰撞检测, 通常的操作 in / len / bool / iter 都对这个group使用。in      test if a Sprite is contained len     the number of Sprites contained bool    test if any Sprites are contained iter    iterate through all the Sprites pygame.sprite.spritecollide() - 在与另一个精灵相交的组中查找精灵spritecollide(sprite, group, dokill, collided = None) -> Sprite_list返回一个sprite列表,其中包含与另一个 Sprite 相交的 Group 中的所有 Sprite 。 通过比较每个 Sprite 的 Sprite.rect 属性来确定交集。dokill 参数是一个布尔值。如果设置为 True,则将从组中删除所有碰撞的 Sprite 。collided 碰撞参数是一个回调函数,用于计算两个精灵是否发生碰撞。 它应该将两个精灵作为值,并返回一个 bool 值,指示它们是否发生碰撞。 如果未传递碰撞,则所有精灵必须具有 rect 值,该值是 sprite 区域的矩形,将用于计算碰撞。可用的回调函数collide_rect, collide_rect_ratio, collide_circle, collide_circle_ratio, collide_mask pygame.sprite.collide_rect - 使用 rects 检测两个精灵之间的碰撞。Collision detection between two sprites, using rects. 使用函数pygame rect colliderect检测碰撞并将结果返回给*collide, 精灵必须具有 ‘rect’ 属性。collide_rect(left, right) -> boolpygame.sprite.collide_rect_ratio - 使用按比例缩放的 rects 检测两个精灵之间的碰撞。Collision detection between two sprites, using rects scaled to a ratio. 使用 ratio 创建,然后将实例作为碰撞回调函数传递给 *collide 函数。ratio 是浮点数 - 1.0 是相同的大小,2.0 是两倍大,0.5 是大小的一半。collide_rect_ratio(ratio) -> collided_callablepygame.sprite.collide_circle - 使用圆圈检测两个精灵之间的碰撞。*Collision detection between two sprites, using circles.*测试两个精灵之间的碰撞,通过测试以查看精灵中心的两个圆是否重叠。如果精灵具有 radius(半径) 属性,用于创建圆,否则会创建一个足够大的圆,以完全包围由 rect 属性给出的精灵矩形。作为碰撞回调函数传递给 *collide 函数。精灵必须具有 rect 和可选的 radius 属性。collide_circle(left, right) -> boolpygame.sprite.collide_circle_ratio - 使用按比例缩放的圆圈检测两个精灵之间的碰撞。Collision detection between two sprites, using circles scaled to a ratio. 使用浮点数 ratio 创建,然后将实例作为碰撞回调函数传递给 *collide 函数。ratio 是浮点数 - 1.0 是相同的大小,2.0 是两倍大,0.5 是大小的一半。两个精灵之间的碰撞创建的可调用测试,通过测试以查看以精灵为中心的两个圆是否重叠,在通过存储的比例缩放圆半径之后。如果精灵具有 radius 半径属性,用于创建圆,否则会创建一个足够大的圆,以完全包围由 rect 属性给出的精灵矩形。打算作为碰撞回调函数传递给 *collide 函数。精灵必须具有 rect 和可选的 radius 属性。collide_circle_ratio(ratio) -> collided_callablepygame.sprite.collide_mask - 使用蒙版在两个精灵之间进行碰撞检测。*Collision detection between two sprites, using masks. *返回 masks 碰撞的 mask 上的第一个点,如果没有碰撞,则返回 None 。通过测试它们的 bitmasks( pygame.mask.Mask.overlap()) 是否重叠来测试两个精灵之间的碰撞。 如果精灵具有 mask 属性,该属性用作 mask,否则将从精灵图像创建 mask 。 作为碰撞回调函数传递给 *collide 函数。精灵必须具有 rect 和可选的 mask 属性。如果要多次检查碰撞,应该考虑在加载时为精灵创建一个mask。这将提高性能,否则这可能是一个昂贵的功能,因为它会在每次检查碰撞时创建 mask 。# Example of mask creation for a sprite. sprite.mask = pygame.mask.from_surface(sprite.image) collide_mask(sprite1, sprite2) -> (int, int)collide_mask(sprite1, sprite2) -> Nonepygame.sprite.groupcollide - 查找在两个组之间发生碰撞的所有精灵。Find all sprites that collide between two groups.This will find collisions between all the Sprites in two groups. Collision is determined by comparing the Sprite.rect attribute of each Sprite or by using the collided function if it is not None.Every Sprite inside group1 is added to the return dictionary. The value for each item is the list of Sprites in group2 that intersect. 像这个格式{group1_sprite: group2_sprite}如果*collide没有指定回调函数,则所有的sprite需要有rect属性 EG: class Block(pygame.sprite.Sprite):      # Constructor. Pass in the color of the block,     # and its x and y position     def __init__(self, color, width, height):        # Call the parent class (Sprite) constructor        pygame.sprite.Sprite.__init__(self)         # Create an image of the block, and fill it with a color.        # This could also be an image loaded from the disk.        self.image = pygame.Surface([width, height])        self.image.fill(color)         # Fetch the rectangle object that has the dimensions of the image        # Update the position of this object by setting the values of rect.x and rect.y        # give radius and mask attribute        self.rect = self.image.get_rect()        self.radius = self.rect.width / 2        self.mask = pygame.image.from_surface(self.image)  class File(pygame.sprite.Sprite):      # Constructor. Pass in the color of the block,     # and its x and y position     def __init__(self, color, width, height):        # Call the parent class (Sprite) constructor        pygame.sprite.Sprite.__init__(self)         # Create an image of the block, and fill it with a color.        # This could also be an image loaded from the disk.        self.image = pygame.Surface([width, height])        self.image.fill(color)         # Fetch the rectangle object that has the dimensions of the image        # Update the position of this object by setting the values of rect.x and rect.y        self.rect = self.image.get_rect()        self.radius = self.rect.width / 2        self.mask = pygame.image.from_surface(self.image)      block_group = pygame.sprite.Group() for i in range(5):     block = Block(color, width, height)     block_group.add(block)          # there is another sprite group called file_group, which have same setting as block_group. file_group = pygame.sprite.Group() for i in range(5):     file = File(color, width, height)     file_group.add(file)          # the collide check will like:     hit_list1 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_rect     hit_list2 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_rect_ratio(.75))     hit_list3 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_circle     hit_list4 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_circle_ratio(.25))     hit_list5 = pygame.sprite.spritecollide(block, file_group, False, pygame.sprite.collide_mask     # select the collided function whatever you like     hit_list6 = pygame.sprite.spritecollide(block_group, file_group, False, False, pygame.sprite.collide_XXX) 
  • [技术干货] Perl 和 StrawberryPerl 与 ActivePerl 的区别详解【转】
    篇文章主要介绍了Perl 和 StrawberryPerl 与 ActivePerl 的区别详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下Perl 是 Practical Extraction and Report Language 的缩写 "实用报表提取语言"。ActiveStatePerl 和 Strawberry Perl 在 Windows 平台上Perl的编译器。Perl  于后两者的关系 是 C 语言和 linux 系统有自带的GCC 的关系。ActiveState Perl和 Strawberry Perl最大的区别是 Strawberry Perl 里面有多包含一些 CPAN 里的模块,所以Strawberry Perl 下载的安装文件有 80多M, 而ActiveState Perl 只有20M 左右。ActiveState Perl: ActiveState提供了一个免费的社区版本和一个商业支持的Perl用于Win32和Perl的二进制分布。Strawberry Perl:用于Windows的100%开源Perl,使用来自CPAN的模块不需要二进制包。ActivePerl含了包括有 四套开发工具程序:Perl for Win32、Perl for ISAPI、PerlScript、Perl Package Manager可以让用户编写出适用于unix,windows,linux系统的的CGI程序。使用Perl Package Manager来管理包 ppm install xxx.ppd在Unix 系统和 Mac OS X 系统默认都有安装Perl 的编译器。可以通过perl -v 命令查看安装的版本。Windows上还有一个常见的是Cygwin的Perl。
  • [技术干货] Bat脚本-timeout 命令(延时执行)【转】
    做一个延时执行的批处理命令,选用timeout命令来实现,但是碰到一个情况是写完后直接双击运行时,timeout 命令运行不了,每次运行到timeout的时候,命令就会跳到.bta文件的开头重新执行,后来选择管理员权限运行就可以了概述做一个延时执行的批处理命令,选用timeout命令来实现,但是碰到一个情况是写完后直接双击运行时,timeout 命令运行不了,每次运行到timeout的时候,命令就会跳到.bta文件的开头重新执行,后来选择管理员权限运行就可以了。命令-timeout在命令行中运行timeout /?可以得到该命令的说明C:\Users\L>timeout /?TIMEOUT [/T] timeout [/NOBREAK]描述:这个工具接受超时参数,等候一段指定的时间(秒)或等按任意键。它还接受一个参数,忽视按键。参数列表:/T timeout 指定等候的秒数。有效范围从 -1 到 99999 秒。/NOBREAK 忽略按键并等待指定的时间。/? 显示此帮助消息。注意: 超时值 -1 表示无限期地等待按键。示例:TIMEOUT /?TIMEOUT /T 10TIMEOUT /T 300 /NOBREAKTIMEOUT /T -1问题复现然后参考大哥们的方法写了以下代码,保存成timeout.bat文件;@echo offrem 打印当前时间echo 当前时间【%time%】rem 进行延时5stimeout /nobreak /t 5rem 延时后的时间echo 延时后的时间【%time%】rem 加入需要执行的代码-开始rem 加入需要执行的代码-结束pause一直在重复打印时间;然后我把回显打开后发现;::@echo off代码每次运行到timeout这里都没有执行,然后就跳到文件的第一行去了;使用管理员权限运行就不会重新跳到第一行
  • [技术干货] Bat脚本-Call,Start,直接调用,goto 四种方式调用批处理【转】
    1、call命令CALL从一个批处理程序调用另一个批处理程序,并且不终止父批处理程序。call命令主要有2种用法,一种是调用其他批处理程序(*.bat,*.exe,*.cmd,*.COM),目前常用的是*.exe文件和*.bat文件;另一种是CALL :label argumentsC:\Users\Administrator>help call从批处理程序调用另一个批处理程序。CALL [drive:][path]filename [batch-parameters]  batch-parameters   指定批处理程序所需的命令行信息。如果命令扩展被启用,CALL 会如下改变:CALL 命令现在将卷标当作 CALL 的目标接受。语法是:    CALL:label arguments一个新的批文件上下文由指定的参数所创建,控制在卷标被指定后传递到语句。您必须通过达到批脚本文件末两次来 "exit" 两次。第一次读到文件末时,控制会回到 CALL 语句的紧后面。第二次会退出批脚本。键入GOTO /?,参看 GOTO :EOF 扩展的描述,此描述允许您从一个批脚本返回。另外,批脚本文本参数参照(%0、%1、等等)已如下改变:     批脚本里的 %* 指出所有的参数(如 %1 %2 %3 %4 %5 ...)     批参数(%n)的替代已被增强。您可以使用以下语法:         %~1         - 删除引号("),扩展 %1         %~f1        - 将 %1 扩展到一个完全合格的路径名         %~d1        - 仅将 %1 扩展到一个驱动器号         %~p1        - 仅将 %1 扩展到一个路径         %~n1        - 仅将 %1 扩展到一个文件名         %~x1        - 仅将 %1 扩展到一个文件扩展名         %~s1        - 扩展的路径只含有短名         %~a1        - 将 %1 扩展到文件属性         %~t1        - 将 %1 扩展到文件的日期/时间         %~z1        - 将 %1 扩展到文件的大小         %~$PATH:1   - 查找列在 PATH 环境变量的目录,并将 %1                       扩展到找到的第一个完全合格的名称。如果                       环境变量名未被定义,或者没有找到文件,                       此修改符会扩展到空字符串    可以组合修改符来取得多重结果:        %~dp1       - 只将 %1 扩展到驱动器号和路径        %~nx1       - 只将 %1 扩展到文件名和扩展名        %~dp$PATH:1 - 在列在 PATH 环境变量中的目录里查找 %1,                      并扩展到找到的第一个文件的驱动器号和路径。        %~ftza1     - 将 %1 扩展到类似 DIR 的输出行。    在上面的例子中,%1 和 PATH 可以被其他有效数值替换。    %~ 语法被一个有效参数号码终止。%~ 修定符不能跟 %* 使用1.1调用批处理命令格式CALL [drive:][path]filename [batch-parameters]创建文件test.bat 调用文件call.bat@echo off set a=环境变量 call call.bat hi hello pause exit /b 02、调用call 和不用call 的区别1、使用call 不终止父处理进程,不用call 调用批处理后,父处理进程终止,不再处理后续命令rem test.bat @echo off set a=环境变量 call call.bat hi hello echo 下一步 pause exit /b 03、goto 命令 帮助文档如下C:\Users\Administrator>help goto将 cmd.exe 定向到批处理程序中带标签的行。GOTO label  label   指定批处理程序中用作标签的文字字符串。标签必须单独一行,并且以冒号打头。如果命令扩展被启用,GOTO 会如下改变:GOTO 命令现在接受目标标签 :EOF,这个标签将控制转移到当前批脚本文件的结尾。不定义就退出批脚本文件,这是一个容易的办法。有关能使该功能有用的 CALL 命令的扩展描述,请键入CALL /?。3.1 goto 后面不需要":",直接加label 3.2 goto 跳至指定label后,不会处理被跳过的命令语句 @echo off goto interCall echo 下一步 :intercall echo hi echo hello PAUSE exit /b 04、start类似于创建一个线程C:\Users\Administrator>help start启动一个单独的窗口运行指定的程序或命令。START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]      [/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]      [/NODE <NUMA node>] [/AFFINITY <hex affinity mask>] [/WAIT] [/B]      [command/program] [parameters]    "title"     在窗口标题栏中显示的标题。    path        启动目录。    B           启动应用程序,但不创建新窗口。应用程序已忽略 ^C 处理。                除非应用程序启用 ^C 处理,否则 ^Break 是唯一可以中断                该应用程序的方式。    I           新的环境将是传递给 cmd.exe 的原始环境,而不是当前环境。    MIN         以最小化方式启动窗口。    MAX         以最大化方式启动窗口。    SEPARATE    在单独的内存空间中启动 16 位 Windows 程序。    SHARED      在共享内存空间中启动 16 位 Windows 程序。    LOW         在 IDLE 优先级类中启动应用程序。    NORMAL      在 NORMAL 优先级类中启动应用程序。    HIGH        在 HIGH 优先级类中启动应用程序。    REALTIME    在 REALTIME 优先级类中启动应用程序。    ABOVENORMAL 在 ABOVENORMAL 优先级类中启动应用程序。    BELOWNORMAL 在 BELOWNORMAL 优先级类中启动应用程序。    NODE        将首选非一致性内存结构 (NUMA) 节点指定为十进制整数。    AFFINITY    将处理器关联掩码指定为十六进制数字。进程被限制在这些                处理器上运行。                当 /AFFINITY 和 /NODE 结合时,会对关联掩码进行不同的解释。                指定关联掩码,正如 NUMA 节点的处理器掩码正确移动到零位                起始位置一样。进程被限制在指定关联掩码和 NUMA 节点之间的                那些通用处理器上运行。如果没有通用处理器,则进程被限制在                指定的 NUMA 节点上运行。    WAIT        启动应用程序并等待它终止。    command/program                如果它是内部 cmd 命令或批文件,则该命令处理器是使用                cmd.exe 的 /K 开关运行的。这表示运行该命令之后,该窗口                将仍然存在。                如果它不是内部 cmd 命令或批文件,则它就是一个程序,并将                作为一个窗口化应用程序或控制台应用程序运行。    parameters  这些是传递给 command/program 的参数。注意: 在 64 位平台上不支持 SEPARATE 和 SHARED 选项。通过指定 /NODE,可按照利用 NUMA 系统中的内存区域的方式创建进程。例如,可以创建两个完全通过共享内存互相通信的进程以共享相同的首选 NUMA 节点,从而最大限度地减少内存延迟。如有可能,它们即会分配来自相同 NUMA 节点的内存,并且会在指定节点之外的处理器上自由运行。    启动 /NODE 1 application1.exe    启动 /NODE 1 application2.exe这两个进程可被进一步限制在相同 NUMA 节点内的指定处理器上运行。在以下示例中, application1 在节点的两个低顺序处理器上运行,而 application2在该节点的其后两个处理器上运行。该示例假定指定节点至少具有四个逻辑处理器。请注意,节点号可更改为该计算机的任何有效节点号,而无需更改关联掩码。    启动 /NODE 1 /AFFINITY 0x3 application1.exe    启动 /NODE 1 /AFFINITY 0xc application2.exe如果命令扩展被启用,通过命令行或 START 命令的外部命令调用会如下改变:将文件名作为命令键入,非可执行文件可以通过文件关联调用。    (例如,WORD.DOC 会调用跟 .DOC 文件扩展名关联的应用程序)。    关于如何从命令脚本内部创建这些关联,请参阅 ASSOC 和FTYPE 命令。执行的应用程序是 32-位 GUI 应用程序时,CMD.EXE 不等应用程序终止就返回命令提示符。如果在命令脚本内执行,该新行为则不会发生。如果执行的命令行的第一个符号是不带扩展名或路径修饰符的字符串 "CMD","CMD" 会被 COMSPEC 变量的数值所替换。这防止从当前目录提取 CMD.EXE。如果执行的命令行的第一个符号没有扩展名,CMD.EXE 会使用PATHEXT 环境变量的数值来决定要以什么顺序寻找哪些扩展名。PATHEXT 变量的默认值是:        .COM;.EXE;.BAT;.CMD    请注意,该语法跟 PATH 变量的一样,分号隔开不同的元素。查找可执行文件时,如果没有相配的扩展名,看一看该名称是否与目录名相配。如果确实如此,START 会在那个路径上调用Explorer。如果从命令行执行,则等同于对那个路径作 CD /D。4.1  可以和 第2段“调用call 和不用call 的区别” 代码作对比@echo off set a=环境变量 start call.bat hi hello echo 下一步 pause exit /b 0call.bat内容如下 rem call.bat echo %1 echo %2 echo %a% pause
  • [技术干货] Bat脚本之在文件中查找多个字符串并保存到文件中【转】
    概述本文讲述的是对文本的内容进行检索,找到需要匹配的字符串并挑出对应字符串输出到新的文本中,实现文本内容过滤的效果。背景本人在开发的过程中,经常会打印一些 log 数据来监测系统是否运行正常,但是有时候 log 数据特别大,且有时候会有一些 log 和当前问题不相关,需要过滤掉,所以想写一个可以提取出我所需要信息的脚本来完成log 数据的提取。需求1、可以提取多个字符串内容;2、可以输出到另外的文本中,不对原文件进行修改;需求分析根据这个需求,可以有多个方法实现,其实简单的就是对文本的内容进行查找,当文件小的时候,其实是可以使用 Notepad++ 这样的软件进行查找,但是 Notepad++ 是有大文件限制的,所以我的想法是通过 bat 脚本的方式进行处理。需求实现@echo off rem 需要查找的第1个字符串 set str1="" rem 需要查找的第2个字符串 set str2="" rem 需要查找的第3个字符串 set str3="" rem 需要查找的文件 set filename="" rem 在当前脚本处查找1、2、3字符串并在输出到当前路径生成的 output.txt 文件 findstr /r "%str1% %str2% %str3%" %filename% > output.txt pause 实现功能1、可以查找多个字符串;2、可以将查找到的字符串输出到新的文本文件;缺点1、查找的字符串不能含有空格;使用示例比如我当前有一个文本文件(test.txt)的内容如下:test1test2test3test4test5test6而我需要查找“test1”和“test5”,则可以新建一个 txt 文件,输入修改后的脚本内容为@echo off rem 需要查找的第1个字符串 set str1="test1" rem 需要查找的第2个字符串 set str2="test5" rem 需要查找的文件 set filename="test.txt" rem 在当前脚本处查找1、2字符串并在输出到当前路径生成的 output.txt 文件 findstr /r "%str1% %str2%" %filename% > output.txt pause 
  • [技术干货] python 配置uwsgi 启动Django框架的详细教程【转】
    1. 安装pip31yum install python34-pip2. 安装python34devel1yum install python34-devel3. pip3 安装依赖1pip3 install -r requirements4. 安装uwsgi1pip3 install uwsgi编写test.py测试uwsgidef application(env, start_response):     start_response('200 OK', [('Content-Type','text/html')])     return [b"Hello World"] # python3     #return ["Hello World"] # python25. uwsgi 配置 (simp)编写uwsgi.ini,以wsgi方式启动uwsgi,此时无法通过web访问的方式测试是否启动, #uwsgi配置文件 [uwsgi]  # 转发给nginx 的端口 socker=:9000 #http=:9000 # 项目目录 master=true chdir = /home/oper/simp/Weekreport wsgi-file = Weekreport/wsgi.py # 进程数 workers = 5 processes = 5 threads = 2 buffer-size = 130000 # 设置日志目录 daemonize = /home/oper/simp/Weekreport/log/uwsgi.log stats=%(chdir)/uwsgi/uwsgi.status pidfile=%(chdir)/uwsgi/uwsgi.pid uwsgi启动的linux shell命令,项目在/home/oper/simp/Weekreport下 # 启动 uwsgi --ini /home/oper/Weekreport/uwsgi.ini # 停止 uwsgi --stop /home/oper/Weekreport/uwsgi/uwsgi.pid  # 启动 uwsgi --ini /home/oper/Weekreport/uwsgi.ini # 停止 uwsgi --stop /home/oper/Weekreport/uwsgi/uwsgi.pid 如控制台出现以下提示,八成是成功了WSGI app 0 (mountpoint='') ready in 0 seconds on interpreter 0x12b9fa0 pid: 2402 (default app) mountpoint  already configured. skip. uWSGI running as root, you can use --uid/--gid/--chroot options *** WARNING: you are running uWSGI as root !!! (use the --uid flag) ***  *** uWSGI is running in multiple interpreter mode *** spawned uWSGI worker 1 (and the only) (pid: 2402, cores: 1) 
  • [技术干货] Python中itertools简介使用介绍【转】
    Python中itertools模块一、 简介itertools是python内置的模块,使用简单且功能强大官方文档地址:cid:link_0itertools模块标准化了一个快速、高效利用内存的核心工具集,这些工具本身或组合都很有用。它们一起形成了“迭代器代数”,这使得在纯Python中有可能创建简洁又高效的专用工具。同时,itertools模块是python的内置库,我们可以直接使用,不需要进行额外的安装这里讲解一些常用的函数,其余函数请到官方文档查看学习。二、 使用介绍1、 常用迭代器1.1 chain函数介绍:chain可以把一组迭代对象串联起来,形成一个更大的迭代器语法:(class) chain(*iterables: Iterable[str])import itertools l1 = ["A", "B"] l2 = ["C", "D"] print(list(itertools.chain(l1, l2)))  # 将两个列表展开,当然,也可以用到一些可迭代对象里面去,比如说字符串等,返回一个可迭代对象1.2 groupby函数介绍:groupby 把迭代器中相邻的重复元素(key)挑出来放一起语法:(class) groupby(iterable: Iterable[_T1@__new__], key: None = ...import itertools for key, value in itertools.groupby("hello world! My name is Steve Anthony"):     print(key, list(value))      """结合key使用""" import itertools data = [     (1, "Make", 93),     (1, "Jack", 100),      (2, "Lucy", 90) ] for key, value in itertools.groupby(data, key=lambda student: student[0]):     print(key, list(value))2、 无穷迭代器2.1 count函数作用:生成无界限序列,count(start=0, step=1) ,示例从100开始,步长为2,循环10,打印对应值;必须手动break,count()会一直循环。语法:count(start: int, [step: _Step = ...]) import itertools  for i in itertools.count(10):     print(i)= 2.2 cycle函数作用:对可迭代容器里面的元素进行无限循环语法:(class) cycle(__iterable: Iterable[int], /) import itertools  for i in itertools.cycle(range(10)):     print(i) 
  • [技术干货] Python3.10 Generator生成器Coroutine原生协程详解【转】
    普遍意义上讲,生成器是一种特殊的迭代器,它可以在执行过程中暂停并在恢复执行时保留它的状态。而协程,则可以让一个函数在执行过程中暂停并在恢复执行时保留它的状态,在Python3.10中,原生协程的实现手段,就是生成器,或者说的更具体一些:协程就是一种特殊的生成器,而生成器,就是协程的入门心法。协程底层实现我们知道,Python3.10中可以使用async和await关键字来实现原生协程函数的定义和调度,但其实,我们也可以利用生成器达到协程的效果,生成器函数和普通函数的区别在于,生成器函数使用 yield 语句来暂停执行并返回结果。例如,下面是一个使用生成器函数实现的简单协程:def my_coroutine():       while True:           x = yield           print(x)   # 使用生成器函数创建协程   coroutine = my_coroutine()   # 启动协程   next(coroutine)   # 在协程中传入数据   coroutine.send(1)   coroutine.send(2)   coroutine.send(3) ➜  mydemo git:(master) ✗ /opt/homebrew/bin/python3.10 "/Users/liuyue/wodfan/work/mydemo/src/test.py"  在上面的代码中,生成器函数 my_coroutine 使用了一个无限循环来实现协程的逻辑。每当调用 send 方法时,协程就会从 yield 语句处恢复执行,并将传入的参数赋值给变量 x。如此,就完成了协程执行-》阻塞-》切换-》回调的工作流模式。当然,作为事件循环机制,协程服务启动可能无限期地运行,要关闭协程服务,可以使用生成器的close()方法。当一个协程被关闭时,它会生成GeneratorExit异常,该异常可以用生成器的方式进行捕获:def my_coroutine():       try :           while True:               x = yield               print(x)       except GeneratorExit:               print("协程关闭")   # 使用生成器函数创建协程   coroutine = my_coroutine()   # 启动协程   next(coroutine)   # 在协程中传入数据   coroutine.send(1)   coroutine.send(2)   coroutine.send(3)   coroutine.close() 程序返回:➜  mydemo git:(master) ✗ /opt/homebrew/bin/python3.10 "/Users/liuyue/wodfan/work/mydemo/src/test.py"  1  2  3  协程关闭业务场景在实际业务场景中,我们也可以使用生成器来模拟协程流程,主要体现在数据的IO流操作中,假设我们需要从本地往服务器传输数据,首先建立链接对象:class Connection:       def __init__(self, addr):           self.addr = addr       def transmit(self, data):           print(f"X: {data[0]}, Y: {data[1]} sent to {self.addr}") 随后建立生成器函数:def send_to_server(conn):       while True:           try:               raw_data = yield               raw_data = raw_data.split(' ')               coords = (float(raw_data[0]), float(raw_data[1]))               conn.transmit(coords)           except ConnectionError:               print("链接丢失,进行回调")               conn = Connection("重新连接v3u.cn") 利用生成器调用链接类的transmit方法进行数据的模拟传输,如果链接断开,则会触发回调重新连接,执行逻辑:if __name__ == '__main__':       conn = Connection("v3u.cn")       sender = send_to_server(conn)       sender.send(None)       for i in range(1, 6):           sender.send(f"{100/i} {200/i}")       # 模拟链接断开       conn.addr = None       sender.throw(ConnectionError)        for i in range(1, 6):           sender.send(f"{100/i} {200/i}") 程序返回:X: 100.0, Y: 200.0 sent to v3u.cn   X: 50.0, Y: 100.0 sent to v3u.cn   X: 33.333333333333336, Y: 66.66666666666667 sent to v3u.cn   X: 25.0, Y: 50.0 sent to v3u.cn   X: 20.0, Y: 40.0 sent to v3u.cn   链接丢失,进行回调   X: 100.0, Y: 200.0 sent to 重新连接v3u.cn   X: 50.0, Y: 100.0 sent to 重新连接v3u.cn   X: 33.333333333333336, Y: 66.66666666666667 sent to 重新连接v3u.cn   X: 25.0, Y: 50.0 sent to 重新连接v3u.cn   X: 20.0, Y: 40.0 sent to 重新连接v3u.cn 如此,我们就可以利用生成器的“状态保留”机制来控制网络链接突然断开的回调补救措施了。
  • [技术干货] Python encode()方法和decode()方法详解【转】
    Python encode()方法encode() 方法为字符串类型(str)提供的方法,用于将 str 类型转换成 bytes 类型,这个过程也称为“编码”。encode() 方法的语法格式如下:1str.encode([encoding="utf-8"][,errors="strict"])注意,格式中用 [] 括起来的参数为可选参数,也就是说,在使用此方法时,可以使用 [] 中的参数,也可以不使用。该方法各个参数的含义如表 1 所示。表 1 encode()参数及含义参数含义str表示要进行转换的字符串。encoding = "utf-8"指定进行编码时采用的字符编码,该选项默认采用 utf-8 编码。例如,如果想使用简体中文,可以设置 gb2312。当方法中只使用这一个参数时,可以省略前边的“encoding=”,直接写编码格式,例如 str.encode("UTF-8")。errors = "strict"指定错误处理方式,其可选择值可以是:strict:遇到非法字符就抛出异常。ignore:忽略非法字符。replace:用“?”替换非法字符。xmlcharrefreplace:使用 xml 的字符引用。该参数的默认值为 strict。注意,使用 encode() 方法对原字符串进行编码,不会直接修改原字符串,如果想修改原字符串,需要重新赋值。【例 1】将 str 类型字符串“C语言”转换成 bytes 类型。>>> str = "C语言" >>> str.encode() b'C\xe8\xaf\xad\xe8\xa8\x80\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91'此方式默认采用 UTF-8 编码,也可以手动指定其它编码格式,例如:>>> str = "C语言" >>> str.encode('GBK') b'C\xd3\xef\xd1\xd4\xd6\xd0\xce\xc4\xcd\xf8'Python decode()方法和 encode() 方法正好相反,decode() 方法用于将 bytes 类型的二进制数据转换为 str 类型,这个过程也称为“解码”。decode() 方法的语法格式如下:bytes.decode([encoding="utf-8"][,errors="strict"])该方法中各参数的含义如表 2 所示。表 2 decode()参数及含义参数含义bytes表示要进行转换的二进制数据。encoding="utf-8"指定解码时采用的字符编码,默认采用 utf-8 格式。当方法中只使用这一个参数时,可以省略“encoding=”,直接写编码方式即可。注意,对 bytes 类型数据解码,要选择和当初编码时一样的格式。errors = "strict"指定错误处理方式,其可选择值可以是:strict:遇到非法字符就抛出异常。ignore:忽略非法字符。replace:用“?”替换非法字符。xmlcharrefreplace:使用 xml 的字符引用。该参数的默认值为 strict。【例 2】>>> str = "C语言" >>> bytes=str.encode() >>> bytes.decode() 'C语言'
  • [技术干货] python中的json数据和pyecharts模块入门示例教程【转】
    一·json数据格式1.什么是jsonJSON是一种轻量级的数据交互格式。可以按照.JSON指定的格式去组织和封装数据JSON本质上是一个带有特定格式的字符串主要功能json就是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互类似于:·国际通用语言-英语;中国56个民族不同地区的通用语言-普通话2.json有什么用各种编程语言存储数据的容器不尽相同,在Python中有字典dict这样的数据类型,而其它语言可能没有对应的字典为了让不同的语言都能够相互通用的互相传递数据,JSON就是一种非常良好的中转数据格式。如下图,以Python和C语言互传数据为例:3.json格式数据转化json数据的格式就是python中的字典或者列表里面嵌套的是字典4.python数据和json数据的相互转化#导入json模块 import json #准备合格式jsom格式要求的python数据 data=[{"name":"张三","age":12},{"name":"李四","age":22}] #通过json.dumps(data)方法把python数据转化为json格式 data1=json.dumps(data) print(f"data1的类型是{type(data1)},内容是{data1}") #通过json.loads(data)方法把json数据转化为python数据 data2=json.loads(data1) print(f"data2的类型是{type(data2)},内容是{data2}")
  • [技术干货] Python 中的json常见用法实例详解【转】
    博主在开发一些C端小软件时,喜欢用json作为序列化方案,故总结下python中json库常见用法。导包自带的库,无需额外安装。1import jsonapi介绍序列化:这里可以理解为将python中的各种数据结构转化为json字符串的过程。涉及api:dump、dumps反序列化:将输入的json字符串,转化为python对象的过程。涉及api:load、loads加s和不加s的区别:以反序列化为例,如果需要从文件中读取数据,则使用load,直接传入文件描述符。简而言之,就是需要从文件中读写数据时,使用load、dump,否则使用loads、dumps常见用法json转python内置对象json会被适当地转化为python中的list或者dic类型的对象。字典对象代码示例:user_dic = json.loads('{"name": "admin", "age": 20, "children": {"name": "child1", "age": 1}}')print(type(user_dic))print(user_dic)运行结果:<class 'dict'>{'name': 'admin', 'age': 20, 'children': {'name': 'child1', 'age': 1}}
  • [技术干货] 用RPA打印九九乘法表
    用WeAutomate RPA实现九九乘法表输出!
总条数:2474 到第 页
上滑加载中