关于python3.x:在-Python-中迭代地遍历两个列表

在 Python 中迭代地遍历两个列表并同时进行操作是一种常见的需要,能够通过多种办法实现,包含应用内建函数 zip(),列表推导式,以及更高级的迭代器和生成器。在这篇具体的指南中,咱们将摸索不同的办法来同时遍历两个列表,并执行各种操作。这些办法不仅高效而且灵便,可能满足多样化的编程需要。 应用 zip() 函数同时遍历列表zip() 函数是 Python 中一个十分有用的内建函数,它能够将多个可迭代对象打包成一个元组的迭代器。当你有两个或更多的列表须要同时遍历时,zip() 函数可能让你轻松地实现这一目标。每次迭代它会从每个可迭代对象中取出一个元素,将它们组合成一个元组。 list1 = [1, 2, 3]list2 = ['a', 'b', 'c']for number, letter in zip(list1, list2): print(f`{number}: {letter}`)这段代码会输入: 1: a2: b3: c如果列表的长度不同,zip() 函数会进行于最短的输出序列。如果须要解决不等长的列表,并保留所有元素,能够应用 itertools.zip_longest()。 利用列表推导式进行操作列表推导式是 Python 中疾速生成列表的一种办法,它能够通过对现有列表的操作和过滤来创立新的列表。当须要对两个列表进行遍历,并对每对元素执行某些操作时,能够联合应用列表推导式和 zip() 函数。 result = [f`{number}-{letter}` for number, letter in zip(list1, list2)]print(result)这会生成一个新的列表,其中蕴含了 list1 和 list2 中相应元素的组合: [`1-a`, `2-b`, `3-c`]应用 enumerate() 和 zip() 解决带索引的遍历在某些状况下,你可能须要在遍历两个列表的同时,保留元素的索引。这时能够应用 enumerate() 函数与 zip() 函数联合来实现。enumerate() 会返回每个元素的索引及其值,这样就能够在遍历过程中应用这些索引。 for index, (number, letter) in enumerate(zip(list1, list2)): print(f`Index {index}: {number} is paired with {letter}`)这将为每对元素提供索引和值,使得操作更加灵便。 ...

February 21, 2024 · 1 min · jiezi

关于python3.x:python3-使用-Selenium-自动化测试或爬取数据

第一步,先装置工具://默认在liunx环境运行,其余环境差不多,装置形式有点区别1.下载 google-chrome-stable_current_x86_64.rpm 装置google-chrome --version 2.下载 chromedriver_linux64.zip 装置chromedriver --version 如果这样两个装置胜利就能够下一步了。 第二步,启动模拟器from pyvirtualdisplay import Displaydisplay = Display(visible=0, size=(800, 800)) display.start() 第三步,创立Chrome WebDriverdriver = webdriver.Chrome() 留神,以上只在2步liunx上面才须要做的,win环境能够间接指定浏览器的驱动器也能够执行,比方我的驱动地位driver = webdriver.Chrome("C:\Program Files (x86)\Google\Chrome\App\chromedriver.exe")第四步,尝试拜访URLdriver.get(url) 第五步,减少等待时间为10秒,应用显式期待来减少等待时间,确保 Selenium 有足够的工夫来查找或交互元素wait = WebDriverWait(driver, 10) 当初就能够获取网页元素了,比方我想获取titletitle = driver.title 或者想获取其中的某个IDwait.until(EC.presence_of_element_located((By.ID, ID)) 获取其中的元素wait.until(EC.visibility_of_element_located((By.TAG_NAME, "h1")))wait.until(EC.visibility_of_element_located((By.ID, "ID")))wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "[class*='Text']"))) 要留神presence_of_element_located和visibility_of_element_located的区别1.presence_of_element_located:这个条件用于期待页面上的元素呈现在 DOM 构造中,但并不关怀元素是否可见或是否被暗藏。当应用这个条件时,Selenium 会期待直到页面上的元素在 DOM 中存在,即便元素不可见或被遮挡也会满足条件。这个条件通常用于期待元素加载实现,但不须要思考元素的可见性,例如期待一个页面加载的 spinner 隐没。2.visibility_of_element_located:这个条件用于期待页面上的元素在 DOM 构造中存在并且可见。当应用这个条件时,Selenium 会期待直到元素在 DOM 中存在并且满足 CSS 款式或布局上的条件,使得它对用户可见。这个条件通常用于期待元素加载实现并且在页面上可见,例如期待一个按钮呈现并且能够被用户点击。 如果想点击按钮能够这样操作button = driver.find_element_by_id("myButton") # 替换为按钮的理论 IDbutton.click() 执行其余测试操作... 最初须要敞开浏览器driver.quit()

September 26, 2023 · 1 min · jiezi

关于python3.x:基于folium绘制黑河腾冲线胡焕庸线

背景黑河腾冲线,又名胡焕庸线,是咱们人口密度散布的的近似分界线。明天基于folium,应用python来绘制这条线。 代码# -*- coding:UTF-8 -*-# region 引入必要依赖from selfPyTools.mapModule import *# endregion# 筹备一个地图类对象, 增加 智图GeoQ 的瓦片图地图 = 地图类().增加瓦片.智图GeoQ().地图# 增加一行网页题目地图.增加网页题目(网页题目款式类(题目文本='感激智图GeoQ提供的根底瓦片资源', 文本字体='楷体', 文本色彩=色彩名.灰))# 生成一个折线对象(折线是由多段间接段组成的,所以一个直线段也能够看成一个折线,只是只有一段而已)折线 = 折线类(线条款式=线条款式类(透明度=0), 线上文本款式=线上文本款式类(文本=' ★ ', 文本尺寸px=18, 文本色彩=色彩名.红))折线.增加门路点(罕用坐标.腾冲市)折线.增加门路点(罕用坐标.黑河市)# 生成一个图层,用来绘制折线折线层 = 地图.增加图层('黑河-腾冲线, 胡焕庸线', 默认显示=True)# 将折线增加到图层上地图.增加标记(折线层, 折线)# 将地图对象生成一个html的文档保留,并顺便打印这个文档地图.反对坐标拾取.容许资源置换.生成html(文档名='黑河-腾冲线 胡焕庸线', 指标门路='.').关上()以上代码中, 所引入的MapModule模块是一个封装了folium模块的自定义模块,提供了不便的地图定义接口。以上代码中,咱们学生成了一个地图类对象,并在这个对像上增加了智图GeoQ做为根底瓦片。以上代码中,咱们为地图增加了一行网页题目,“感激智图GeoQ提供了根底瓦片资源”,并设置了字体和字体色彩。以上代码中,咱们生成了一个折线,用来示意胡焕庸线,咱们设置的折线的透明度为0(即不可见),并设置了折线的线上文本为 ★,并设置了★的字体尺寸和色彩。(咱们应用★来示意这条线)。以上代码中,咱们为折线增加了两个端点,两点定义一条直线/线段嘛。咱们别离增加了黑河市和腾冲市的坐标做为折线的两个端点。以上代码中,咱们将折线增加到一个名叫“黑河——腾冲线,胡焕庸线”的图层中以上代码中,咱们将整顿好数据的地图生成一个html文档保留下来,并关上阅览。上图中,咱们看到在地图上,有一条由红色★组成的线,这条线就是黑河腾冲线,又名胡焕庸线。随着地图的放大和放大,★的数量会自适应调整哦。 小结以上就是明天分享的基于folium生成的黑河—腾冲线了,心愿能够帮忙到大家。

September 10, 2023 · 1 min · jiezi

关于python3.x:python的内置方法

一、查看内置函数print("内置函数=", dir(__builtins__))二、内置函数2.1、type() 和 isinstance()用处:查问变量所指的对象类型举例: a, b, c, d = 20, 5.5, True, 1 + 3j# type()print(type(a)) # <class 'int'>print(type(b)) # <class 'float'>print(type(c)) # <class 'bool'>print(type(d)) # <class 'complex'># isinstance()print(isinstance(a, int)) # Trueprint(isinstance(b, float)) # Trueprint(isinstance(c, bool)) # Trueprint(isinstance(d, complex)) # True区别: type()不会认为子类是一种父类类型isinstance()会认为子类是一种父类类型class A: passclass B(A): passprint(isinstance(A(), A)) # Trueprint(type(A()) == A) # Trueprint(isinstance(B(), A)) # Trueprint(type(B()) == A) # False2.2、ord()用处:将字符转换为相应的整数值eg: x = b"hello"print(x[0]) # 104print(ord("h")) # 104if x[0] == ord("h"): print("The first element is 'h'") # The first element is 'h'三、python推导式3.1、列表推导式格局:表达式 for 变量 in 列表 或者 表达式 for 变量 in 列表 if 条件eg: ...

July 8, 2023 · 2 min · jiezi

关于python3.x:探索Python的反射与内省代码的自我察觉

Python中的反射与内省容许代码觉察和批改它本人。反射指的是程序在运行时能够拜访、检测和批改它本人的构造或行为的一种能力。而内省则更侧重于查看对象的类型和属性,比方查看一个对象是否有某个属性或办法,以及查看对象的文档字符串等。本文将深入探讨Python的反射与内省能力。 一、根底的反射函数Python提供了许多内置函数来反对反射。比方type,id,getattr,setattr和hasattr等。 class MyClass: def __init__(self): self.my_attribute = 123 self.another_attribute = "Hello" def my_method(self): passinstance = MyClass()# 应用type检测对象类型print(type(instance)) # 输入: <class '__main__.MyClass'># 应用id获取对象内存地址print(id(instance)) # 应用getattr获取属性值print(getattr(instance, 'my_attribute')) # 输入: 123# 应用setattr批改属性值setattr(instance, 'my_attribute', 456)print(getattr(instance, 'my_attribute')) # 输入: 456# 应用hasattr检测是否有某个属性print(hasattr(instance, 'nonexistent_attribute')) # 输入: False二、dir函数和__dir__办法dir函数和__dir__办法能够用来获取一个对象的所有属性和办法。 class MyClass: def __init__(self): self.my_attribute = 123 def my_method(self): passinstance = MyClass()print(dir(instance)) 输入将蕴含my_attribute和my_method,以及一些由Python主动增加的魔法办法。 三、反射在动静操作中的利用反射在须要进行动静操作时十分有用,比方咱们能够基于字符串的名字来调用办法: class MyClass: def my_method(self): return "Hello, world!"instance = MyClass()method_name = 'my_method'method = getattr(instance, method_name)print(method()) # 输入: Hello, world!四、内省的一些有用工具Python规范库提供了一些用于内省的有用工具,比方inspect模块: ...

June 11, 2023 · 1 min · jiezi

关于python3.x:同行盆友来稿初探Python变量

什么是变量在Python编程语言中,变量是用于存储数据值的标识符。它们能够用来援用数据值,而不是间接应用值自身。能够应用等号(=)运算符来将一个值赋给一个变量。 变量数据类型有那些变量类型有以下几种: 1. 整型(int):示意整数,例如:`42`、`-3`、`1000`等。2. 浮点型(float):示意浮点数(即带小数点的数),例如:`3.14`、`-2.5`、`0.0`等。3. 布尔型(bool):示意真或假,只有两个取值:`True`和`False`。4. 字符串型(str):示意字符串,即由零个或多个字符组成的序列,例如:`"hello"`、`"world"`、`"123"`等。5. 列表型(list):示意一个有序的元素汇合,其中的元素能够是不同类型的数据,例如:`[1, 2, "apple", True]`。6. 元组型(tuple):与列表相似,也是一个有序的元素汇合,然而元组中的元素是不能被批改的,例如:`(1, 2, "apple", True)`。7. 汇合型(set):示意一个无序的元素汇合,其中的元素不能反复,例如:`{1, 2, 3, 4}`。8. 字典型(dict):示意一个键值对的汇合,其中的每个键都惟一对应一个值,例如:`{"name": "Alice", "age": 30}`。上面分享几个小案例。实战案例上面是Python中定义变量的语法: variable_name = value其中,variable_name示意变量名,=是赋值操作符,value是要赋给变量的值。在Python中,变量的类型是动静的,这意味着它们在申明时不须要指定类型,而是依据赋给它们的值主动确定类型。 上面是一些示例: # 定义一个整型变量x = 10# 定义一个字符串变量name = "John"# 定义一个布尔型变量is_valid = True# 定义一个列表变量numbers = [1, 2, 3, 4, 5]# 定义一个字典变量person = {"name": "John", "age": 30}在Python中,能够通过应用变量名来援用变量的值,例如: print(x) print(name) print(is_valid) print(numbers) print(person)如何应用布尔型变量 # 定义布尔变量is_sunny = Trueis_raining = False# 应用布尔变量进行条件判断if is_sunny:    print("It's a sunny day!")else:    print("It's not a sunny day.")# 应用布尔变量进行循环管制while is_raining:    print("It's still raining...")这里定义了两个布尔变量 is_sunny 和 is_raining,而后别离应用它们进行条件判断和循环管制。在条件语句中,如果布尔变量的值为 True,则执行 if 代码块中的语句;否则,执行 else 代码块中的语句。在循环中,只有当布尔变量的值为 True 时才会执行循环体中的语句。如果变量的值在循环执行过程中变为 False,循环就会终止。须要留神的是,在Python中,布尔值 True 和 False 实际上是整数类型的子类,其中 True 等于整数 1,而 False 等于整数 0。因而,能够在须要整数类型的中央应用布尔值。在Python3中,列表变量用于存储一组有序的元素,能够是雷同类型的数据,也能够是不同类型的数据。你能够通过以下形式来创立一个列表: my_list = [1, 2, 3, 4, 5]  # 蕴含整型元素的列表my_list2 = ["apple", "banana", "orange"]  # 蕴含字符串元素的列表my_list3 = [1, "apple", True]  # 蕴含不同类型元素的列表能够应用列表索引来拜访列表中的元素。Python中的列表索引从0开始,因而第一个元素的索引为0,第二个元素的索引为1,以此类推。例如,要拜访 my_list 中的第一个元素,能够应用以下语法:first_element = my_list[3]print(first_element)你还能够应用切片语法来拜访列表的一部分。切片语法应用起始索引和完结索引之间的冒号 : 来指定一个范畴,例如:# 获取my_list的前三个元素first_three_elements = my_list[0:3]# 获取my_list2的第二个和第三个元素second_and_third_elements = my_list2[1:3]print(second_and_third_elements)在这个例子中,first_three_elements 的值将是 [1, 2, 3],而 second_and_third_elements 的值将是 ["banana", "orange"]。列表还提供了许多有用的办法,例如 append() 用于在列表开端增加元素, insert() 用于在指定地位插入元素, remove() 用于删除指定元素等等。在Python3中,字典变量用于存储一组键值对,其中每个键都是惟一的,而值能够是任意类型的数据。你能够通过以下形式来创立一个字典: my_dict = {"name": "Alice", "age": 30, "city": "New York"}在这个例子中,咱们创立了一个蕴含三个键值对的字典,其中键为 "name"、"age" 和 "city",对应的值别离为 "Alice"、30 和 "New York"。能够应用键来拜访字典中的值,例如: name = my_dict["name"]age = my_dict["age"]# 打印进去print(name)print(age)还能够应用字典提供的许多办法来操作字典,例如 keys() 办法用于获取字典中的所有键,values() 办法用于获取字典中的所有值,items() 办法用于获取字典中的所有键值对等等。 # 向字典中增加一个键值对my_dict["gender"] = "female"# 删除字典中的一个键值对del my_dict["city"]# 获取字典中所有键keys = my_dict.keys()# 获取字典中所有值values = my_dict.values()# 获取字典中所有键值对items = my_dict.items()在Python3中,变量的类型是动静的,也就是说,在定义变量时不须要指定其类型,而是在运行时依据变量的值来确定其类型。这种动静类型的个性使得Python3编程更加灵便和不便。本文转载于WX公众号:不背锅运维(喜爱的盆友关注咱们):https://mp.weixin.qq.com/s/INnS2x8R__-Uu-Mc6xZwgw

May 7, 2023 · 1 min · jiezi

关于python3.x:Python爬虫入门指南

爬虫(Web Crawler)是指一种可能主动从互联网上获取数据的程序。它能够主动拜访并抓取互联网上的网页,并从中提取数据。爬虫技术被广泛应用于搜索引擎、数据挖掘、信息处理等畛域。在Python中,咱们能够应用第三方库 requests 和 BeautifulSoup 来编写爬虫程序。上面,咱们将一步步学习如何应用这两个库来编写爬虫程序。 一、入门1. 装置 requests 和 BeautifulSoup 库咱们首先须要装置 requests 和 BeautifulSoup 库。能够应用以下命令进行装置: pip install requestspip install beautifulsoup42. 应用 requests 库发送申请咱们能够应用 requests 库中的 get() 办法来发送 HTTP GET 申请,并取得响应。例如,以下代码能够获取百度首页的 HTML 内容: import requestsurl = 'https://www.baidu.com'response = requests.get(url)print(response.text)3. 解析 HTML 内容咱们能够应用 BeautifulSoup 库来解析 HTML 内容。例如,以下代码能够获取百度首页的题目: import requestsfrom bs4 import BeautifulSoupurl = 'https://www.baidu.com'response = requests.get(url)soup = BeautifulSoup(response.text, 'html.parser')title = soup.title.stringprint(title)4. 获取链接咱们能够应用 BeautifulSoup 库来获取 HTML 内容中的链接。例如,以下代码能够获取百度首页的所有链接: import requestsfrom bs4 import BeautifulSoupurl = 'https://www.baidu.com'response = requests.get(url)soup = BeautifulSoup(response.text, 'html.parser')links = []for link in soup.find_all('a'): links.append(link.get('href'))print(links)5. 存储数据咱们能够应用 Python 中的文件操作来存储数据。例如,以下代码能够将获取到的链接存储到一个文本文件中: ...

April 25, 2023 · 3 min · jiezi

关于python3.x:python爬虫爬取大学排名

一、程序实现须要的几个函数库requests和 bs4其中requests库用来爬取网页内容,应用beautifulsoup4库剖析网页中的数据,提取学校排名并且打印进去。首先这两个库是要提前下载的:须要咱们应用cmd进入到咱们python下载所在的文件中的Scripts文件中,输出下列指令下载即可 import requestsfrom bs4 import BeautifulSoupimport bs4二、程序剖析简略剖析一下,其实绝对简略,次要由以下这几个次要的函数组成, 1.def getHTMLText(url):(1).try.....except语句,个别应用其实现异样解决机制从而管制用户输出的罕用办法。 try: <语句>except <name>: <语句> #如果在try部份引发了名为'name'的异样,则执行这段代码else: <语句> #如果没有异样产生,则执行这段代码(2)res = requests.get(url,headers=headers)向网站发动申请,并获取响应对象 参数: url :须要抓取的URL地址headers : 申请头timeout : 超时工夫,超过工夫会抛出异样响应对象(res)属性 encoding :响应字符编码 res.encoding = 'utf-8'text :字符串 网站源码content :字节流 字符串网站源码status_code :HTTP响应码url :理论数据的URL地址 三、残缺代码import requestsfrom bs4 import BeautifulSoupimport bs4def getHTMLText(url): try: r = requests.get(url, timeout=30) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return ""def fillUnivLIst(ulist, html): soup = bs4.BeautifulSoup(html, "html.parser") for tr in soup.find('tbody').children: # 检测tag类型,过滤非tag类型标签 if isinstance(tr, bs4.element.Tag): tds = tr('td') ulist.append([str(tr('td')[0].contents[0]).strip(), tds[1].a.string, str(tr('td')[4].contents[0]).strip()]) return ulistdef printUnivList(ulist, num): # tplt = "{0:^10}\t{1:{3}^6}\t{2:^10}" print("{:^10}\t{:^6}\t{:^10}".format("排名", "学校名称", "总分")) # print(tplt.format("排名","学校名称","总分",chr=(12288))) for i in range(num): u = ulist[i] print("{:^10}\t{:^6}\t{:^10}".format(u[0], u[1], u[2]))# print(tplt.format(u[0],u[1],u[2],chr=(12288)))def main(): ulist = [] url = 'https://www.shanghairanking.cn/rankings/bcur/2020' html = getHTMLText(url) ulist = fillUnivLIst(ulist, html) printUnivList(ulist, 20)main()四、成果展现 ...

April 25, 2023 · 1 min · jiezi

关于python3.x:python随笔

一、python内置关键字和内置函数import keyword# 查看python内置关键字print("内置关键字=", keyword.kwlist)# 查看python内置函数print("内置函数=", dir(__builtins__)) 二、格式化输入的三种形式2.1、f格式化实现格局:print(f"a={a}")eg: name = "TOM"age = 13print(f"name={name},age={age}") 2.2、% 格式化实现格局:print("a,b,c:%d,%d,%d" % (a,b,c)) python字符串格式化罕用符号用处%c格式化字符及其ASCII码%d格式化整数%o格式化八进制数(不能带小数点)%x格式化十六进制数(不能带小数点)%s格式化字符串%f格式化浮点数,能够管制保留小数点后几位数%e将数字转化成迷信计数法的模式a = "TOM"b = 36c = 21.63# 将数字依照ASCII码转换成对应的字符print("输入:%c" % b)# 本义输入字符串类型的数据print("输入:%s" % a)# 将数字类型的数据本义成整数print("输入:%d" % c)# 将数字本义成迷信计数法的模式print("输入:%e" % b)# 将整数转化成八进制数据print("输入:%o" % b)# 将整数转化成十六进制数据print("输入:%x" % b)# 格式化浮点数,默认保留小数点后六位print("输入:%f" % b) 罕用的格式化辅助符号解释阐明.用来扭转小数点前面保留小数的位数 (用于%f)*定义宽度和小数点的精度-用于数据做对齐+用于显示数据的正负号# 保留小数点后三位,点前面跟上保留小数的位数print("输入:%.3f" % 3.69859425)# %加数字用于示意输入的后果向右平移几个空格print("输入:%10s" % "TOM")# 在输入数字后果后面加上正负号print('输入:%+d' % 12)# 用*代替字符串中的变量,不便批改输入时的格局要求"""上面代码的解释阐明:第一个*等于10为宽度.前面代码保留几位小数第二个*等于3小数点前面的位数"""print("输入:%*.*f" % (10, 3, 12.3432)) 2.3、format() 格式化实现格局:print("a={} b={} c={}".format(a, b, c)) {}中罕用办法款式型/功能型解释阐明{:*<8}款式型用 * 填充斥长度为8的字符串且本义的内容靠左{:*>8}款式型用 * 填充斥长度为8的字符串且本义的内容靠右{:*^8}款式型用 * 填充斥长度为8的字符串且本义的内容靠上{:f}功能型将数据类型转换成浮点类型的数据(默认保留小数后6位){:.n}款式型管制浮点数保留n位数,包含小数点后的数据{:+}款式型用于显示数据的正负号{:e}功能型将数字转化成迷信计数法模式{:%}功能型将数据转化成百分制的模式{:b}功能型将数据转化成二进制的模式{:d}功能型将数据转化成十进制的模式{:o}功能型将数据转化成八进制的模式{:x}功能型将数据转化成十六进制的模式# 用 * 填充斥长度为8的字符串且本义的内容靠左print("输入:{:*<8}".format("狗狗"))# 用 # 填充斥长度为8的字符串且本义的内容靠右print("输入:{:*>8}".format("狗狗"))# 用 # 填充斥长度为8的字符串且本义的内容靠上print("输入:{:*^8}".format("狗狗"))# 默认保留6位小数,主动四舍五入print("输入:{:f}".format(3.123456789))# 管制浮点数保留几位数字,主动四舍五入print("输入:{:.5}".format(3.12345))# 显示正负号print("输入:{:+}".format(50))# 输入迷信计数法模式print("输入:{:e}".format(3.696))# 输入百分制模式并无小数print("输入:{:.0%}".format(0.5))# 输入二进制print("输入:{:b}".format(8))# 输入十进制print("输入:{:d}".format(12))# 输入八进制print("输入:{:o}".format(99))# 输入十六进制print("输入:{:x}".format(15)) ...

April 11, 2023 · 1 min · jiezi

关于python3.x:如何创建python-虚拟环境venv

venv是什么venv是Python 3中的一个内置模块,它提供了一种创立Python虚拟环境的办法。虚拟环境是一种隔离Python环境的机制,它能够让咱们在同一台机器上应用不同的Python解释器和库,而不会相互烦扰。在Python 2中,能够应用第三方工具如virtualenv来创立虚拟环境,达到与venv类似的成果。 如果不应用虚拟环境,可能会遇到以下问题: 版本抵触:不同的Python工程可能会依赖不同的Python版本或第三方库版本,如果不应用虚拟环境,就可能会导致版本抵触,从而导致程序无奈失常运行。难以保护:在没有虚拟环境的状况下,可能须要手动装置和治理多个Python版本和第三方库版本,这会减少开发和保护的难度。难以迁徙:如果须要将程序从一台计算机迁徙到另一台计算机,可能须要手动装置和配置所需的Python环境和第三方库,这会减少迁徙的难度和危险。应用虚拟环境能够解决上述问题,它提供了一种隔离Python环境的机制,能够在不同的Python工程中应用不同的Python版本和第三方库版本,从而防止版本抵触,简化开发和保护,以及不便迁徙。因而,倡议在开发Python程序时应用虚拟环境。 如何应用venv 创立虚拟环境要创立一个虚拟环境,须要应用venv模块提供的venv命令。例如,要在当前目录下创立一个名为myenv的虚拟环境,能够运行以下命令: python3 -m venv myenv 激活虚拟环境而后通过以下形式激活虚拟环境: 在Linux或macOS中,运行以下命令: source myenv/bin/activate一旦激活了虚拟环境,咱们就能够应用pip装置所需的第三方库,并在该虚构环境中运行Python程序。当实现工作后,能够应用deactivate命令退出虚拟环境。 在应用venv前,我本地装置的requests库如下: ➜ python_test pip3 list | grep requestsrequests 2.28.1创立一个虚拟环境后,激活虚拟环境后,就多了(myenv) ➜提示符,同时应用pip3 list来查看是没有装置requests库的 python3 -m venv myenv➜ python_test source myenv/bin/activate(myenv) ➜ python_test pip3 list | grep requestsWARNING: You are using pip version 20.2.3; however, version 23.0.1 is available.而后我装置一个requests库,发现装置了一个更新的版本2.28.2 (myenv) ➜ python_test pip3 install requestsCollecting requests Using cached requests-2.28.2-py3-none-any.whl (62 kB)Requirement already satisfied: charset-normalizer<4,>=2 in ./myenv/lib/python3.8/site-packages (from requests) (3.1.0)Requirement already satisfied: certifi>=2017.4.17 in ./myenv/lib/python3.8/site-packages (from requests) (2022.12.7)Requirement already satisfied: urllib3<1.27,>=1.21.1 in ./myenv/lib/python3.8/site-packages (from requests) (1.26.14)Requirement already satisfied: idna<4,>=2.5 in ./myenv/lib/python3.8/site-packages (from requests) (3.4)Installing collected packages: requestsSuccessfully installed requests-2.28.2WARNING: You are using pip version 20.2.3; however, version 23.0.1 is available. ...

March 13, 2023 · 1 min · jiezi

关于python3.x:jumpserver-api创建资产

jumpserver apidomain+/api/docs pythonimport requests, jsonjms_url = 'http://jumpserver.xixxxshu.com'token = 'exxxxxxxxxxxxxxxxxxxxxxxxx'headers = { "Authorization": 'Token ' + token, "Content-Type": "application/json", "Accept": "application/json", 'X-JMS-ORG': '4xxxxxxxxxxxxxxxxxxxxxxxxxxxx'}# 获取所有用户def get_user_all(): url = jms_url + '/api/v1/users/users/' response = requests.get(url, headers=headers) user_list = json.loads(response.text) count = 1 # print(user_list) for i in user_list: count += 1 print(i) print(count)## # 获取监控指标# def get_prometheus_metric():# url = jms_url + "/api/v1/prometheus/metrics/"# response = requests.get(url, headers=headers)# print(response.text)# return response.text# 获取所有资产节点def get_node_all(): url = jms_url + "/api/v1/assets/nodes/" response = requests.get(url, headers=headers) node_list = json.loads(response.text) count = 1 for i in node_list: count += 1 print(i) print(count) return response.json()# 查看以后token(即admin)的所有资产def get_asset_all(): url = jms_url + "/api/v1/assets/assets/" response = requests.get(url, headers=headers) node_list = json.loads(response.text) count = 1 for i in node_list: count += 1 print(i) print(count) return response.json()#################################################################################################### 创立资产节点def assets_nodes_create(node_name): node_data = { "value": node_name } url = jms_url + "/api/v1/assets/nodes/" node_info = get_node_info(node_name) if node_info: # 依据node_name去查问,如果查到了阐明曾经有了。 print("{name}已存在, id: {id}".format(name=node_name, id=node_info[0]["id"])) else: data = json.dumps(node_data) resp = requests.post(url, headers=headers, data=data) return resp.json()def get_assets_list_by_ip(ip): url = jms_url + "/api/v1/assets/assets/" response = requests.get(url, headers=headers, params={ "ip": ip }) return response.json()# 查看资产节点信息def get_node_info(node_name): url = jms_url + "/api/v1/assets/nodes/" response = requests.get(url, headers=headers, params={ "value": node_name }) print(response.text) return response.json()def asset_create(ip, hostname, node_id, comment): asset_Data = { "ip": ip, "hostname": hostname, "platform": "Linux", "protocol": "ssh", "port": 22, "is_active": True, "nodes": [ node_id ], "org_id": "4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", "org_name": "Ownerx辰", "comment": comment } url = jms_url + "/api/v1/assets/assets/" data = json.dumps(asset_Data) response = requests.post(url, headers=headers, data=data) print(json.loads(response.text))# 运行创立服务器资产def run_create_assets(node_name, project_name, ip, comment): # 节点id,无节点时创立节点 node_info = get_node_info(node_name) if len(node_info) == 0: node_id = assets_nodes_create(node_name) else: node_id = node_info[0]["id"] # 治理用户 id hostname = "{ip}_{project_name}".format(ip=ip, project_name=project_name) # 查IP,创立资产 ip_info = get_assets_list_by_ip(ip) if ip_info: print("%s 已存在,nodes: %s" % (ip_info[0]["ip"], ip_info[0]["nodes"])) else: asset_create(ip, hostname, node_id, comment)#run_create_assets("Ownerx辰", "xxxx", "10xx.xx.xx9", "测试")def get_org_info(): url = jms_url + "/api/v1/orgs/orgs/" response = requests.get(url, headers=headers) org_list = response.text print(org_list) for i in org_list.split("id"): print(i) return response.json()def get_user_gorup(): url = jms_url + "/api/v1/xpack/cloud/accounts/" response = requests.get(url, headers=headers) for i in response.text.split(","): print(i) # print(response.text) return response.json()GOpackage mainimport ( "bytes" "encoding/json" "fmt" "io/ioutil" "log" "net/http")const ( JmsServerURL = "http://juxxxxxxxxxxxxxxngshu.com" JMSToken = "exxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxb" ORG = "4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx96" // ORG myself)type JumpServerCreateJson struct { Ip interface{} `json:"ip"` Hostname interface{} `json:"hostname"` Platform string `json:"platform"` Protocol string `json:"protocol"` Port int `json:"port"` IsActive interface{} `json:"is_active"` Nodes []interface{} `json:"nodes"` OrgId string `json:"org_id"` OrgName string `json:"org_name"` Comment interface{} `json:"comment"`}func GetOrgList(jmsurl, token string) { url := jmsurl + "/api/v1/orgs/orgs/" client := &http.Client{} req, err := http.NewRequest("GET", url, nil) req.Header.Add("Authorization", "Token "+token) req.Header.Add("X-JMS-ORG", ORG) resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(string(body))}func GetNodeInfo(jmsUrl string, token string, nodeName string, org string) { uri := jmsUrl + "/api/v1/assets/nodes/?value=" + nodeName client := &http.Client{} req, err := http.NewRequest("GET", uri, nil) req.Header.Add("Authorization", "Token "+token) req.Header.Add("X-JMS-ORG", org) resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(string(body))}func GetAssetsInfo(jmsUrl string, token string, ip string) { uri := jmsUrl + "/api/v1/assets/assets/?ip=" + ip client := &http.Client{} req, err := http.NewRequest("GET", uri, nil) req.Header.Add("Authorization", "Token "+token) req.Header.Add("X-JMS-ORG", ORG) resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(string(body))}func CreateAsset(jmsUrl string, token string, ip string, homeName string, comment string, platform string, nodeId string, orgId string, orgName string) { bodyJson := `{ "ip": "10.2x3.1x.2x1", "hostname": "hostname", "platform": "Linux", "protocol": "ssh", "port": 22, "is_active": True, "nodes": [ "node_id" ], "org_id": "4xxxxxxxxxxxxxxxxxxxxxx6", "org_name": "Ownxxxx", "comment": "comment" }` var j JumpServerCreateJson err := json.Unmarshal([]byte(bodyJson), &j) if err != nil { fmt.Println("err is %v: ", err) } j.Ip = ip j.OrgId = orgId j.Comment = comment j.Hostname = homeName j.OrgName = orgName j.Nodes = []interface{}{nodeId} if platform == "Linux" { fmt.Println("Linux ,body Wie ist") } else { j.Port = 3389 j.Protocol = "rdp" j.Platform = "Windows" fmt.Println("Windows ,body change") } data, err := json.Marshal(j) if err != nil { fmt.Println("err was %v", err) } fmt.Println(string(data)) reader := bytes.NewReader(data) uri := jmsUrl + "/api/v1/assets/assets/" client := &http.Client{} req, err := http.NewRequest("POST", uri, reader) req.Header.Add("Authorization", "Token "+token) req.Header.Add("X-JMS-ORG", orgId) resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Fatal(err) } fmt.Println(string(body))}func main() { //GetOrgList(JmsServerURL, JMSToken) //GetNodeInfo(JmsServerURL, JMSToken, "Ownxxx", "1xxxxxxxxxxxxxxxxxxxxxxxxxxxxe") //GetAssetsInfo(JmsServerURL, JMSToken, "10.2x.1x1.xx9")}

February 22, 2023 · 4 min · jiezi

关于python3.x:如何创建一个超时后不会被kill的python子进程

在subprocess之前,创立一个新过程的形式有很多种,如os.system()、os.spawn*办法等。为了对立创立过程的形式,python社区提议应用subprocess模块作为创立过程的规范形式,用来替换os.system和os.spawn*等形式。 subprocess模块的应用subprocess.run办法签名如下 subprocess.run(*args*, *** , *stdin=None*, *input=None*, *stdout=None*, *stderr=None*, *capture_output=False*, *shell=False*, *cwd=None*, *timeout=None*, *check=False*, *encoding=None*, *errors=None*, *text=None*, *env=None*, *universal_newlines=None*, ***other_popen_kwargs*)run办法是创立过程的举荐办法,只有run办法无奈满足需要的时候才思考应用popen办法。run会梗塞式地执行args参数提供的命令,直到命令执行完结或者超时。args能够是字符串数组或者字符串,当args为字符串时,shell参数必须为True。 我想创立一个子过程,应用adb install命令给vivo/oppo/xiaomi手机装置app,然而vivo/oppo/xiaomi手机会弹出二次确认窗口,如果不进行点击操作,则无奈装置App。所以我就想创立一个子过程,超时后再接着由UI自动化的形式来点击确认按钮。这就要求超时后装置过程不能退出。run办法尽管有timeout参数,然而子过程会在超时被kill掉。 以下动画演示了手动装置app时须要二次确认,手动点击持续装置后,能够在控制台看到以下输入 Perform Streamed Install Success证实曾经装置胜利了。   以下动画演示了应用run命令,超时后装置过程被kill掉了,在控制台无奈看到胜利装置的日志输入。二次确认后,装置过程就不见了。 对应的代码: import subprocessif __name__ == '__main__':    proc=subprocess.run('adb install -g -r -t app-uiautomator.apk', shell=True, timeout=10, capture_output=True)  subprocess.Popensubprocess模块里过程的创立和治理都是Popen类解决的,它让开发者非常灵活地解决一些不常见的场景。  - *class* subprocess.Popen(*args*, *bufsize=- 1*, *executable=None*, *stdin=None*, *stdout=None*, *stderr=None*, *preexec_fn=None*, *close_fds=True*, *shell=False*, *cwd=None*, *env=None*, *universal_newlines=None*, *startupinfo=None*, *creationflags=0*, *restore_signals=True*, *start_new_session=False*, *pass_fds=()* , *** , *group=None*, *extra_groups=None*, *user=None*, *umask=- 1*, *encoding=None*, *errors=None*, *text=None*, *pipesize=- 1*, *process_group=None*)Popen类有以下几个办法: ...

January 29, 2023 · 1 min · jiezi

关于python3.x:python-获取Azure-下的虚拟机列表

azure事实上,微软Azure并没有一个所谓的“API拜访凭证”的概念,咱们须要通过它的“Active Directory”中的应用程序Client信息来进行API的拜访。而且相较其它云厂商而言,微软Azure的API拜访凭证略显简单,且须要通过多个步骤获取,它由订阅(Subscription)ID、租户(Tenant)ID、Client ID和Client Secret四个局部形成。获取微软Azure的订阅(Subscription)ID每个Azure用户在应用时都会接触到订阅的概念。您在购买Azure产品之前,必须先创立一个订阅,而后须要在这个订阅下购买云资源,云资源不能跨订阅拜访。因而,当您存在多个订阅时,请您确保输出的订阅ID是您须要导入的云资源所属订阅,否则可能会呈现无奈列出云资源的状况。 登录Azure控制台,在左侧菜单栏抉择“老本治理+计费”(菜单程序可自定义调整,截图仅供示意)。 在概述中,找到您要导入的云资源所属订阅,获取订阅ID。如果您有多个订阅,都心愿通过安恒云来治理,那么请在安恒云中创立多个云账户分批导入。 获取微软Azure的租户(Tenant)ID租户是Active Directory中的一个概念,示意组织;租户蕴含组织中的用户以及用户的相干信息(如明码、用户配置文件数据、权限等)。 (1)在Azure控制台的左侧菜单栏中抉择“Azure Active Directory”。 在“Azure Active Directory”的属性页面,能够看到“租户ID”,该ID即为Azure的租户(Tenant)ID。 获取微软Azure的Client信息所谓Client信息,即Active Directory中应用程序的API访问信息,包含Client ID和Client Secret两局部。 (1)在Azure Active Directory中,点击<利用注册>,将会列呈现有的所有应用程序,建议您新建一个专门的应用程序供安恒云调用API。点击<新注册>。 (2)在注册应用程序页面,输出以下信息后点击<注册>。 名称:xxxxxxxx(不能用中文) 受反对的账户类型:倡议抉择“任何组织目录” 重定向URI:填写https://xxxxxxxx (3)注册实现后如下图所示,该应用程序(客户端)ID即是Client ID (4)点击刚注册的利用“xxxx”的<证书和明码>,点击<新客户端明码>,阐明填写“安恒云API拜访”,截止期限抉择“从不”,而后点击<增加>即可。 应用程序资源受权(1)取得Client信息后,还须要将应用程序在资源上进行受权:在左侧菜单栏抉择“资源组”。 (2)查看资源列表,抉择您心愿导入到安恒云的资源组,进入后点击<访问控制(标识和拜访治理)>子菜单,在授予对此资源的拜访权限区域点击<增加角色调配> 3)在增加角色调配区域,角色抉择“所有者”,将拜访权限调配到抉择默认的“用户、组或服务主体”,抉择文本框中输出后面创立的管理员账号关键字,选中后能够看到上面所选成员中存在该账号,点击<保留>。 (4)此时在访问控制(标识和拜访治理)的角色调配页签下,在所有者中即减少了您创立的管理员账号。尔后您便能够应用该账号创立的Client信息作为API拜访凭证,将资源导入到xx Codefrom azure.identity import ClientSecretCredentialfrom azure.mgmt.resource import ResourceManagementClientfrom azure.mgmt.network import NetworkManagementClientfrom azure.mgmt.compute import ComputeManagementClientSubscription_Id = "4xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Tenant_Id = "axxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Client_Id = "7exxxxxxxxxxxxxxxxxxxxxxxxxxxxx"Secret = "wxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"GROUP_NAME = 'Cxx'AZRUE_URL = 'https://management.chinacloudapi.cn'credentials = ClientSecretCredential( tenant_id=Tenant_Id, client_id=Client_Id, client_secret=Secret)resource_client = ResourceManagementClient(credential=credentials, subscription_id=Subscription_Id, base_url=AZRUE_URL, credential_scopes=["https://management.chinacloudapi.cn/.default"])compute_client = ComputeManagementClient(credential=credentials, subscription_id=Subscription_Id, base_url=AZRUE_URL, credential_scopes=["https://management.chinacloudapi.cn/.default"])network_client = NetworkManagementClient(credential=credentials, subscription_id=Subscription_Id, base_url=AZRUE_URL, credential_scopes=["https://management.chinacloudapi.cn/.default"])### 获取 虚拟机名字列表vm_list = compute_client.virtual_machines.list(GROUP_NAME)vm_name_list = []i = 0for vm in vm_list: array = vm.id.split("/") resource_group = array[4] vm_name = array[-1] statuses = compute_client.virtual_machines.instance_view(resource_group, vm_name).statuses status = len(statuses) >= 2 and statuses[1] vm_name_list.append(vm_name)print(vm_name_list)vm_info_list = []for i in vm_name_list: virtual_machine = compute_client.virtual_machines.get(GROUP_NAME, i) vm_dict = dict() vm_dict['name'] = virtual_machine.name vm_dict['os_type'] = virtual_machine.storage_profile.os_disk.os_type vm_dict['vmSize'] = virtual_machine.hardware_profile.vm_size vm_dict['disk_size'] = virtual_machine.storage_profile.os_disk.disk_size_gb vm_dict['data_disks'] = [] vm_dict['ip'] = [] try: vm_dict['image_reference'] = dict(exact_version=virtual_machine.storage_profile.image_reference.exact_version, sku=virtual_machine.storage_profile.image_reference.offer) except Exception as e: vm_dict['image_reference'] = 'null' for item in virtual_machine.storage_profile.data_disks: vm_dict['data_disks'].append(dict(lun=item.lun, name=item.name, disk_size_gb=item.disk_size_gb)) for item in virtual_machine.network_profile.network_interfaces: network_interface_name = item.id.split('/')[-1] a = network_client.network_interfaces.get(GROUP_NAME, network_interface_name) for ip in a.ip_configurations: vm_dict['ip'].append(ip.private_ip_address) print(vm_dict) vm_info_list.append(vm_dict)print(vm_info_list)输入后果:['Zxxxx6-Server'][ {'name': 'Zxxxxix6-Server', 'os_type': 'Linux', 'vmSize': 'Standard_D4s_v3', 'disk_size': 30, 'data_disks': [], 'ip': ['10.2x.5x.1x'], 'image_reference': {'exact_version': '8.2.2020111800', 'sku': 'CentOS'}}]

January 12, 2023 · 1 min · jiezi

关于python3.x:Linux下Python39任意目录快速编译安装和配置上手实用指南

日期作者版本备注2022-10-06dingbinthu@163.comV1.0 本文叙述在Linux Centos7零碎下,在任意非标准目录(意味着不须要root或sudo权限)通过官网源码包编译装置Python3.9的疾速装置指南。 因编译装置Python3.9可能须要装置一些前置依赖库如openssl,readline等,装置这些尽管也能够逐个下载源码编译装置,但略显繁琐,因而还是举荐通过yum 应用root或sudo权限一键装置前置依赖项。(因而又必须须要root或sudo权限)。当然如果你的零碎这些前置依赖项都装置过了就不须要装置了因而还是能够不须要root或sudo权限的。1. Yum一键装置前置依赖项sudo yum -y install zlib zlib-devel bzip2 bzip2-devel ncurses ncurses-devel readline readline-devel openssl openssl-devel openssl-static xz lzma xz-devel sqlite sqlite-devel gdbm gdbm-devel tk tk-devel libffi libffi-devel2. 下载Python 3.9 官网源码包去https://www.python.org/downlo... 下载Python 3.9.15 的源码包,百度云盘链接地址 。下载后的Python-3.9.15.tgz大概25M很小。 留神:咱们还经常去pypi.org 官网上去下载python库。前面会简略叙述python如何在下载pypi.org上的库文件后执行安装操作的。3. Linux下编译装置Python 3.9cd ${TMP_DIR}tar zxvf Python-3.9.15.tgzcd Python-3.9.15./configure --enable-shared --enable-optimizations CFLAGS=-fPIC --prefix=${INSTALL_DIR}makemake install这里加上--enable-shared和-fPIC之后能够将python3的动态链接库编译进去,个别是libPython.so,大略10-30M,生成的Python可执行程序的运行依赖于这个动静库。如果不指定改选项编译实现后则会生成一个libPython.a,生成的Python可执行程序就齐全包好了该.a的全部内容就不依赖与该.a动态库了。然而如果编译第三方库须要python接口的比方caffe等,则会报错,所以这里倡议加上下面的--enable-shared和-fPIC参数。留神: 如果哪天你要讲python可执行程序拷贝到别的机器,切记要连带上拷贝这个libPython.so.xxx。它的地位就在python装置目标目录下的lib目录下。--enable-optimizations 选项个别倡议加上,它能够使得python执行时增速10%左右。 全程大概5-8分钟即可编译装置结束。 4.Python可用初始配置python3.9编译装置好之后,要到可用或好用状态,还须要如下初始配置。 4.1 .bashrc环境变量配置留神:默认的python3高版本之后生成的可执行程序被命令为了python3 或pip3. 必须 为期建设python 和pip的软连贯。如下操作:cd ${INSTALL_DIR}/binln -sf python3 pythonln -sf pip3 pip接着在~/.bashrc中增加如下环境变量: ...

November 27, 2022 · 2 min · jiezi

关于python3.x:python3-pyVmomi-操作-获取-vcenter-下数据中心-集群-主机-存储-虚拟机等信息

vim 报错能够疏忽#!/usr/bin/python3# coding:utf-8from pyVmomi import vimfrom pyVim.connect import SmartConnect, Disconnect, SmartConnectNoSSLimport atexitdef get_obj(content, vimtype, name=None): # 列表返回,name 能够指定匹配的对象 container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True) obj = [view for view in container.view] return objdef get_esxi_all_info(): esxi_host = {} esxi_list = [] # connect this thing si = SmartConnectNoSSL( host='10.23.1xx.xx', user='rexxxl', pwd='xxxxx', port='443') # disconnect this thing atexit.register(Disconnect, si) content = si.RetrieveContent() esxi_obj = get_obj(content, [vim.HostSystem]) for esxi in esxi_obj: esxi_host[esxi.name] = {'esxi_info': {}, 'datastore': {}, 'network': {}, 'vm': {}} esxi_host[esxi.name]['esxi_info']['厂商'] = esxi.summary.hardware.vendor esxi_host[esxi.name]['esxi_info']['型号'] = esxi.summary.hardware.model for i in esxi.summary.hardware.otherIdentifyingInfo: if isinstance(i, vim.host.SystemIdentificationInfo): esxi_host[esxi.name]['esxi_info']['SN'] = i.identifierValue esxi_host[esxi.name]['esxi_info']['处理器'] = '数量:%s 核数:%s 线程数:%s 频率:%s(%s) ' % (esxi.summary.hardware.numCpuPkgs, esxi.summary.hardware.numCpuCores, esxi.summary.hardware.numCpuThreads, esxi.summary.hardware.cpuMhz, esxi.summary.hardware.cpuModel) try: esxi_host[esxi.name]['esxi_info']['处理器使用率'] = '%.1f%%' % (esxi.summary.quickStats.overallCpuUsage / ( esxi.summary.hardware.numCpuPkgs * esxi.summary.hardware.numCpuCores * esxi.summary.hardware.cpuMhz) * 100) except Exception as e: esxi_host[esxi.name]['esxi_info']['处理器使用率'] = None print(e) esxi_host[esxi.name]['esxi_info']['内存(MB)'] = esxi.summary.hardware.memorySize / 1024 / 1024 try: esxi_host[esxi.name]['esxi_info']['可用内存(MB)'] = '%.1f MB' % ( (esxi.summary.hardware.memorySize / 1024 / 1024) - esxi.summary.quickStats.overallMemoryUsage) except Exception as e: esxi_host[esxi.name]['esxi_info']['可用内存(MB)'] = None print(e) try: esxi_host[esxi.name]['esxi_info']['内存使用率'] = '%.1f%%' % ((esxi.summary.quickStats.overallMemoryUsage / ( esxi.summary.hardware.memorySize / 1024 / 1024)) * 100) except Exception as e: esxi_host[esxi.name]['esxi_info']['内存使用率'] = None print(e) esxi_host[esxi.name]['esxi_info']['零碎'] = esxi.summary.config.product.fullName for ds in esxi.datastore: esxi_host[esxi.name]['datastore'][ds.name] = {} esxi_host[esxi.name]['datastore'][ds.name]['总容量(G)'] = int((ds.summary.capacity) / 1024 / 1024 / 1024) esxi_host[esxi.name]['datastore'][ds.name]['闲暇容量(G)'] = int((ds.summary.freeSpace) / 1024 / 1024 / 1024) esxi_host[esxi.name]['datastore'][ds.name]['类型'] = (ds.summary.type) for nt in esxi.network: esxi_host[esxi.name]['network'][nt.name] = {} esxi_host[esxi.name]['network'][nt.name]['标签ID'] = nt.name for vm in esxi.vm: esxi_host[esxi.name]['vm'][vm.name] = {} esxi_host[esxi.name]['vm'][vm.name]['电源状态'] = vm.runtime.powerState esxi_host[esxi.name]['vm'][vm.name]['CPU(内核总数)'] = vm.config.hardware.numCPU esxi_host[esxi.name]['vm'][vm.name]['内存(总数MB)'] = vm.config.hardware.memoryMB esxi_host[esxi.name]['vm'][vm.name]['零碎信息'] = vm.config.guestFullName if vm.guest.ipAddress: esxi_host[esxi.name]['vm'][vm.name]['IP'] = vm.guest.ipAddress else: esxi_host[esxi.name]['vm'][vm.name]['IP'] = '服务器须要开机后才能够获取' for d in vm.config.hardware.device: if isinstance(d, vim.vm.device.VirtualDisk): esxi_host[esxi.name]['vm'][vm.name][d.deviceInfo.label] = str( (d.capacityInKB) / 1024 / 1024) + ' GB' print("####esxi_host", esxi_host) return esxi_hostdef get_esxi_list(): esxi_list = [] si = SmartConnectNoSSL( host='10.23.1xx.xx', user='rexxxl', pwd='xxxxx', port='443') atexit.register(Disconnect, si) content = si.RetrieveContent() esxi_obj = get_obj(content, [vim.HostSystem]) # print(esxi_obj[1].name) -- 10.23.140.242 for h in esxi_obj: print('ESXI IP:', h.name) esxi_list.append(h.name) return esxi_listdef get_esxi_single_info(esxi_ip): esxi_host = {} si = SmartConnectNoSSL( host='10.23.1xx.xx', user='rexxxl', pwd='xxxxx', port='443') atexit.register(Disconnect, si) content = si.RetrieveContent() esxi_obj = get_obj(content, [vim.HostSystem]) for esxi in esxi_obj: if esxi.name == esxi_ip: esxi_host[esxi.name] = {'esxi_info': {}, 'datastore': {}, 'network': {}, 'vm': {}} esxi_host[esxi.name]['esxi_info']['厂商'] = esxi.summary.hardware.vendor esxi_host[esxi.name]['esxi_info']['型号'] = esxi.summary.hardware.model for i in esxi.summary.hardware.otherIdentifyingInfo: if isinstance(i, vim.host.SystemIdentificationInfo): esxi_host[esxi.name]['esxi_info']['SN'] = i.identifierValue esxi_host[esxi.name]['esxi_info']['处理器'] = '数量:%s 核数:%s 线程数:%s 频率:%s(%s) ' % ( esxi.summary.hardware.numCpuPkgs, esxi.summary.hardware.numCpuCores, esxi.summary.hardware.numCpuThreads, esxi.summary.hardware.cpuMhz, esxi.summary.hardware.cpuModel) try: esxi_host[esxi.name]['esxi_info']['处理器使用率'] = '%.1f%%' % (esxi.summary.quickStats.overallCpuUsage / ( esxi.summary.hardware.numCpuPkgs * esxi.summary.hardware.numCpuCores * esxi.summary.hardware.cpuMhz) * 100) except Exception as e: esxi_host[esxi.name]['esxi_info']['处理器使用率'] = None print(e) esxi_host[esxi.name]['esxi_info']['内存(MB)'] = esxi.summary.hardware.memorySize / 1024 / 1024 try: esxi_host[esxi.name]['esxi_info']['可用内存(MB)'] = '%.1f MB' % ( (esxi.summary.hardware.memorySize / 1024 / 1024) - esxi.summary.quickStats.overallMemoryUsage) except Exception as e: esxi_host[esxi.name]['esxi_info']['可用内存(MB)'] = None print(e) try: esxi_host[esxi.name]['esxi_info']['内存使用率'] = '%.1f%%' % ((esxi.summary.quickStats.overallMemoryUsage / ( esxi.summary.hardware.memorySize / 1024 / 1024)) * 100) except Exception as e: esxi_host[esxi.name]['esxi_info']['内存使用率'] = None print(e) esxi_host[esxi.name]['esxi_info']['零碎'] = esxi.summary.config.product.fullName for ds in esxi.datastore: esxi_host[esxi.name]['datastore'][ds.name] = {} esxi_host[esxi.name]['datastore'][ds.name]['总容量(G)'] = int((ds.summary.capacity) / 1024 / 1024 / 1024) esxi_host[esxi.name]['datastore'][ds.name]['闲暇容量(G)'] = int((ds.summary.freeSpace) / 1024 / 1024 / 1024) esxi_host[esxi.name]['datastore'][ds.name]['类型'] = (ds.summary.type) for nt in esxi.network: esxi_host[esxi.name]['network'][nt.name] = {} esxi_host[esxi.name]['network'][nt.name]['标签ID'] = nt.name for vm in esxi.vm: esxi_host[esxi.name]['vm'][vm.name] = {} esxi_host[esxi.name]['vm'][vm.name]['电源状态'] = vm.runtime.powerState esxi_host[esxi.name]['vm'][vm.name]['CPU(内核总数)'] = vm.config.hardware.numCPU esxi_host[esxi.name]['vm'][vm.name]['内存(总数MB)'] = vm.config.hardware.memoryMB esxi_host[esxi.name]['vm'][vm.name]['零碎信息'] = vm.config.guestFullName if vm.guest.ipAddress: esxi_host[esxi.name]['vm'][vm.name]['IP'] = vm.guest.ipAddress else: esxi_host[esxi.name]['vm'][vm.name]['IP'] = '服务器须要开机后才能够获取' for d in vm.config.hardware.device: if isinstance(d, vim.vm.device.VirtualDisk): esxi_host[esxi.name]['vm'][vm.name][d.deviceInfo.label] = str( (d.capacityInKB) / 1024 / 1024) + ' GB' print("####esxi_host", esxi_host) return esxi_hostdef get_esxi_datacenter(): si = SmartConnectNoSSL( host='10.23.1xx.xx', user='rexxxl', pwd='xxxxx', port='443') atexit.register(Disconnect, si) content = si.RetrieveContent() esxi_obj = get_obj(content, [vim.Datacenter]) #print(esxi_obj[0].hostFolder.childEntity[0].name) data = [] for i in esxi_obj: esxi_list = [] datacenter_data = {'datacenter_name': i.name} for j in i.hostFolder.childEntity: esxi_list.append(j.name) datacenter_data['host_list'] = esxi_list data.append(datacenter_data) return data

October 18, 2022 · 3 min · jiezi

关于python3.x:python3-pyVmomi-操作-vcenter-克隆虚拟机-实例

克隆虚拟机是依赖于虚拟机模板,在虚拟机模板失常的状况下,以上代码可能实现克隆虚拟机并指定IP的操作的,那么先来说一说克隆虚拟机的坑。景象1:虚拟机克隆胜利,虚拟机主动失常开机,但没有指定上网络IP。景象产生的起因:克隆应用的模板没有网络适配器景象2:虚拟机克隆胜利,然而没有自动开机,并且指定网络IP也失败了,在 vSphere上还报了ident.hostName.name异样。景象产生的起因:①虚拟机主机名:不能够用下划线等特殊字符②虚拟机主机名为空景象3:虚拟机克隆胜利,虚拟机主动失常开机,网络指定胜利,但虚拟机网络不通,无奈失常应用网络。景象产生的起因:指定的虚拟机IP和虚拟机所在的网络适配器的网络段不匹配,导致网络不通。补充:当克隆虚拟机,没有集群,层级:数据中心–>文件夹–>主机 vim 飘红能够疏忽code# -*- coding: utf-8 -*-import timeimport tracebackimport loggingfrom pyVim.connect import SmartConnectNoSSL, Disconnectfrom pyVmomi import vimclass VmManage(object): def __init__(self, host, user, password, port, ssl): self.config = None self.host = host self.user = user self.pwd = password self.port = port self.sslContext = ssl try: self.client = SmartConnectNoSSL(host=host, user=user, pwd=password, port=443 ) self.content = self.client.RetrieveContent() self.result = True except Exception as e: self.result = e def _get_all_objs(self, obj_type, folder=None): """ 依据对象类型获取这一类型的所有对象 """ if folder is None: container = self.content.viewManager.CreateContainerView(self.content.rootFolder, obj_type, True) else: container = self.content.viewManager.CreateContainerView(folder, obj_type, True) return container.view def _get_obj(self, obj_type, name): obj = None content = self.client.RetrieveContent() container = content.viewManager.CreateContainerView(content.rootFolder, obj_type, True) for c in container.view: if c.name == name: obj = c break return obj def get_datacenters(self): """ 获取数据核心列表 """ return self._get_all_objs([vim.Datacenter]) # vcenter执行动作期待 def wait_for_task(self, task): """ wait for a vCenter task to finish """ task_done = False while not task_done: print("task.....%s " % task.info.state) if task.info.state == 'success': return {'message': u'执行胜利', 'status': True} if task.info.state == 'error': print("there was an error") return {'message': task.info.error.msg, 'status': True} def handleTask(self, tasks=None): if tasks is None: return False else: from pyVim.task import WaitForTasks try: WaitForTasks(tasks=tasks, si=self.client) except Exception as e: traceback.print_exc() print(str(e)) return False def get_cluster_by_name(self, name=None, datacenter=None): if datacenter: folder = datacenter.hostFolder else: folder = self.content.rootFolder container = self.content.viewManager.CreateContainerView(folder, [vim.ClusterComputeResource], True) clusters = container.view for cluster in clusters: if cluster.name == name: return cluster return None def get_datastore_by_name(self, name, datacenter): datastores = datacenter.datastore for datastore in datastores: if datastore.name == name: return datastore return None def get_host_by_name(self, name, datastore): hosts = datastore.host for host in hosts: print("##get_host_by_name host:", host.key.summary.config.name) if host.key.summary.config.name == name: return host.key return None def get_vms_by_cluster(self, vmFolder): content = self.client.content objView = content.viewManager.CreateContainerView(vmFolder, [vim.VirtualMachine], True) vmList = objView.view objView.Destroy() return vmList def get_customspec(self, vm_ip=None, vm_subnetmask=None, vm_gateway=None, vm_dns=None, vm_domain=None, vm_hostname=None): # guest NIC settings 无关dns和域名的配置谬误 更改了 adaptermaps = [] guest_map = vim.vm.customization.AdapterMapping() guest_map.adapter = vim.vm.customization.IPSettings() guest_map.adapter.ip = vim.vm.customization.FixedIp() guest_map.adapter.ip.ipAddress = vm_ip guest_map.adapter.subnetMask = vm_subnetmask guest_map.adapter.gateway = vm_gateway if vm_domain: guest_map.adapter.dnsDomain = vm_domain adaptermaps.append(guest_map) # DNS settings globalip = vim.vm.customization.GlobalIPSettings() if vm_dns: globalip.dnsServerList = [vm_dns] globalip.dnsSuffixList = vm_domain # Hostname settings ident = vim.vm.customization.LinuxPrep() if vm_domain: ident.domain = vm_domain ident.hostName = vim.vm.customization.FixedName() if vm_hostname: ident.hostName.name = vm_hostname customspec = vim.vm.customization.Specification() customspec.nicSettingMap = adaptermaps customspec.globalIPSettings = globalip customspec.identity = ident return customspec def change_disk_size(self, vm_obj, vm_disk): """ :param vm_obj: 虚拟机对象(模板对象也实用) :param vm_disk: 硬盘大小(单位:G) :return: disk_change 配置列表 """ virtual_disk_devices = [] virtual_disk_device = None virtual_scsi_controller = None # Find the disk device for dev in vm_obj.config.hardware.device: if isinstance(dev, vim.vm.device.VirtualSCSIController): virtual_scsi_controller = dev if isinstance(dev, vim.vm.device.VirtualDisk): virtual_disk_devices.append(dev) for dev in virtual_disk_devices: if dev.controllerKey == virtual_scsi_controller.key: virtual_disk_device = dev new_disk_kb = int(vm_disk) * 1024 * 1024 virtual_disk_spec = vim.vm.device.VirtualDeviceSpec() virtual_disk_spec.operation = \ vim.vm.device.VirtualDeviceSpec.Operation.edit virtual_disk_spec.device = virtual_disk_device virtual_disk_spec.device.capacityInKB = new_disk_kb disk_changes = [] disk_changes.append(virtual_disk_spec) return disk_changes def add_disk(self, vm_obj, capacity): spec = vim.vm.ConfigSpec() dev_changes = [] # capacity 为 存储盘容量将单位改为 G new_disk_kb = capacity * 1024 * 1024 unit_number = 0 # 遍历所有的硬件设施,找适合的地位增加 for dev in vm_obj.config.hardware.device: if hasattr(dev.backing, 'fileName'): unit_number = int(dev.unitNumber) + 1 # unit_number 7 reserved for scsi controller if unit_number == 7: unit_number += 1 if unit_number >= 16: logging.error('we don\'t support this many disks') if isinstance(dev, vim.vm.device.VirtualSCSIController): controller = dev disk_spec = vim.vm.device.VirtualDeviceSpec() disk_spec.fileOperation = "create" disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add disk_spec.device = vim.vm.device.VirtualDisk() disk_spec.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo() disk_spec.device.backing.thinProvisioned = True disk_spec.device.backing.diskMode = 'persistent' disk_spec.device.unitNumber = unit_number disk_spec.device.capacityInKB = new_disk_kb disk_spec.device.controllerKey = controller.key dev_changes.append(disk_spec) return dev_changes def add_disk_to_vm(self, vm_name, capacity): vm_obj = self._get_obj([vim.VirtualMachine], vm_name) spec = vim.vm.ConfigSpec() dev_changes = [] # capacity 为 存储盘容量将单位改为 G new_disk_kb = capacity * 1024 * 1024 unit_number = 0 # 遍历所有的硬件设施,找适合的地位增加 for dev in vm_obj.config.hardware.device: if hasattr(dev.backing, 'fileName'): unit_number = int(dev.unitNumber) + 1 # unit_number 7 reserved for scsi controller if unit_number == 7: unit_number += 1 if unit_number >= 16: logging.error('we don\'t support this many disks') if isinstance(dev, vim.vm.device.VirtualSCSIController): controller = dev disk_spec = vim.vm.device.VirtualDeviceSpec() disk_spec.fileOperation = "create" disk_spec.operation = vim.vm.device.VirtualDeviceSpec.Operation.add disk_spec.device = vim.vm.device.VirtualDisk() disk_spec.device.backing = vim.vm.device.VirtualDisk.FlatVer2BackingInfo() disk_spec.device.backing.thinProvisioned = True disk_spec.device.backing.diskMode = 'persistent' disk_spec.device.unitNumber = unit_number disk_spec.device.capacityInKB = new_disk_kb disk_spec.device.controllerKey = controller.key dev_changes.append(disk_spec) spec.deviceChange = dev_changes task = vm_obj.ReconfigVM_Task(spec=spec) result1 = self.wait_for_task(task) if result1['status']: data = {'message': u'硬盘增加胜利', 'result': True} else: data = {'message': u'硬盘增加失败: %s' % result1['message'], 'result': False} return data def edit_nic(self, vm, network_name, is_vss): device_change = [] data = {'message': None, 'result': False, 'code': 1} for device in vm.config.hardware.device: if isinstance(device, vim.vm.device.VirtualEthernetCard): nicspec = vim.vm.device.VirtualDeviceSpec() nicspec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit nicspec.device = device nicspec.device.wakeOnLanEnabled = True if is_vss: nicspec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo() nicspec.device.backing.network = self._get_obj([vim.Network], network_name) nicspec.device.backing.deviceName = network_name else: network = self._get_obj([vim.dvs.DistributedVirtualPortgroup], network_name) dvs_port_connection = vim.dvs.PortConnection() dvs_port_connection.portgroupKey = network.key dvs_port_connection.switchUuid = network.config.distributedVirtualSwitch.uuid nicspec.device.backing = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo() nicspec.device.backing.port = dvs_port_connection nicspec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo() nicspec.device.connectable.startConnected = True nicspec.device.connectable.allowGuestControl = True device_change.append(nicspec) nicspec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo() nicspec.device.connectable.startConnected = True nicspec.device.connectable.allowGuestControl = True device_change.append(nicspec) break if device_change: config_spec = vim.vm.ConfigSpec(deviceChange=device_change) task = vm.ReconfigVM_Task(config_spec) result = self.wait_for_task(task) if result['status']: power_state = vm.runtime.powerState if power_state == 'poweredOn': stop_task = vm.PowerOff() stop_result = self.wait_for_task(stop_task) # if stop_result['status']: # start_task = vm.PowerOn() # self.wait_for_task(start_task) # else: start_task = vm.PowerOn() self.wait_for_task(start_task) data["message"] = u'更改网络胜利' data["result"] = True data["code"] = 0 else: data["message"] = u'更改网络失败' else: data["message"] = u'网络适配器不存在,无奈批改网络' return data def device_nic(self, vm, network_name, switch_type): """ :param vm: 虚拟机模板对象 :param network_name: 要批改的网络段名称 :param switch_type: 网络段类型 :return: """ device_change = [] no_vlan = False for device in vm.config.hardware.device: # 判断是否存在网络适配器 if isinstance(device, vim.vm.device.VirtualEthernetCard): nicspec = vim.vm.device.VirtualDeviceSpec() # 肯定要是vim.vm.device.VirtualDeviceSpec.Operation.edit 代表编辑 nicspec.operation = vim.vm.device.VirtualDeviceSpec.Operation.edit nicspec.device = device nicspec.device.wakeOnLanEnabled = True if switch_type == 1: # 规范交换机设置 nicspec.device.backing = vim.vm.device.VirtualEthernetCard.NetworkBackingInfo() nicspec.device.backing.network = self._get_obj([vim.Network], network_name) nicspec.device.backing.deviceName = network_name else: # 判断网络段是否在分组交换机网络范畴 network = self._get_obj([vim.dvs.DistributedVirtualPortgroup], network_name) if network is None: logging.error(u'分组交换机没有{0}网段'.format(network_name)) no_vlan = True break # 分布式交换机设置 dvs_port_connection = vim.dvs.PortConnection() dvs_port_connection.portgroupKey = network.key dvs_port_connection.switchUuid = network.config.distributedVirtualSwitch.uuid nicspec.device.backing = vim.vm.device.VirtualEthernetCard.DistributedVirtualPortBackingInfo() nicspec.device.backing.port = dvs_port_connection # 网络段配置设置 nicspec.device.connectable = vim.vm.device.VirtualDevice.ConnectInfo() nicspec.device.connectable.startConnected = True nicspec.device.connectable.allowGuestControl = True device_change.append(nicspec) logging.info('网络适配器设置') break if device_change: return device_change else: if not no_vlan: logging.error(u'网络适配器不存在,无奈批改网络') return device_change def get_vm_ip(self, vm_obj): """ 获取 VM 所有 IP 地址 """ ips = [] for i in vm_obj.guest.net: if i.network: for b in range(6): if i.ipAddress: ips.extend(i.ipAddress) return ips else: print("VM 没有获取到IP地址期待10秒") time.sleep(10) else: print('VM 未配置网卡') return 'VM 未获取到IP地址,请检测网络状态或者 DHCP 服务器' def clone_cluster(self, template_name, vm_name, datacenter_name, datastore_name, cluster_name, host_name=None, cup_num=None, memory=None, vm_ip=None, vm_subnetmask=None, vm_gateway=None, vm_dns=None, vm_domain=None, vm_hostname=None): # 获取模版 template = self._get_obj([vim.VirtualMachine], template_name) # 模版不存在 if template is None: return {'message': u'克隆失败: 模版不存在', 'result': False} else: print(template.name, "模版存在hehe") # 抉择克隆的虚拟机寄存地位,通过数据中心获取对象 datacenter = self._get_obj([vim.Datacenter], datacenter_name) # 数据中心不存在 if datacenter is None: return {'message': u'克隆失败: 数据中心不存在', 'result': False} vmfolder = datacenter.vmFolder # 获取存储 if datastore_name: datastore = self.get_datastore_by_name(datastore_name, datacenter) if datastore is None: return {'message': u'克隆失败: 该数据中心下%s存储不存在' % datastore_name, 'result': False} else: print(datastore.name, "数据中心存储存在") else: # 此处感觉须要批改 datastore = self.get_datastore_by_name(template.datastore[0].info.name, datacenter) if datastore is None: return {'message': u'克隆失败: 该数据中心下%s模版不存在' % template_name, 'result': False} else: print(template.name, datastore, "模版存在hehe") # 获取集群 cluster = self.get_cluster_by_name(cluster_name, datacenter) print("##cluster:", cluster) if cluster is None: print(self.get_host_by_name(host_name, datastore)) return {'message': u'克隆失败: cluster %s no存在' % cluster, 'result': False} else: vms = self.get_vms_by_cluster(cluster) vms_name = [i.name for i in vms] if vm_name in vms_name: return {'message': u'克隆失败: 虚拟机%s曾经存在' % vm_name, 'result': False} resource_pool = cluster.resourcePool relospec = vim.vm.RelocateSpec() relospec.datastore = datastore relospec.pool = resource_pool # 获取主机 if host_name: host = self.get_host_by_name(host_name, datastore) if host is None: return {'message': u'克隆失败: 该存储下%s主机不存在' % host_name, 'result': False} else: relospec.host = host clonespec = vim.vm.CloneSpec() clonespec.location = relospec clonespec.powerOn = True # 设置cpu和内存 if all([vm_ip, vm_subnetmask, vm_gateway, vm_domain]): clonespec.customization = self.get_customspec(vm_ip, vm_subnetmask, vm_gateway, vm_domain, vm_dns, vm_hostname) vmconf = vim.vm.ConfigSpec() if cup_num: vmconf.numCPUs = cup_num if memory: vmconf.memoryMB = memory if vmconf is not None: clonespec.config = vmconf print("cloning VM...") task = template.Clone(folder=vmfolder, name=vm_name, spec=clonespec) result = self.wait_for_task(task) if result['status']: data = {'message': u'克隆胜利', 'result': True} else: data = {'message': u'克隆失败: %s' % result['message'], 'result': False} return data def clone_host(self, template_name, vm_name, datacenter_name, datastore_name, vm_exi_ip, vm_vlan=None, switch_type=None, vm_folder=None, cup_num=None, memory=None, vm_disk=None, vm_add_disk=None, vm_ip=None, vm_subnetmask=None, vm_gateway=None, vm_dns=None, vm_domain=None, vm_hostname=None): # 获取模版 template = self._get_obj([vim.VirtualMachine], template_name) # 模版不存在 if template is None: return {'message': u'克隆失败: 模版不存在', 'result': False} # 抉择克隆的虚拟机寄存地位,通过数据中心获取对象 datacenter = self._get_obj([vim.Datacenter], datacenter_name) # 数据中心不存在 if datacenter is None: return {'message': u'克隆失败: 数据中心不存在', 'result': False} # vm创立门路 if vm_folder: vmfolder = self._get_obj([vim.Folder], vm_folder) else: vmfolder = datacenter.vmFolder # 获取存储 if datastore_name: datastore = self.get_datastore_by_name(datastore_name, datacenter) if datastore is None: return {'message': u'克隆失败: 该数据中心下%s存储不存在' % datastore_name, 'result': False} else: datastore = self.get_datastore_by_name(template.datastore[0].info.name, datacenter) if datastore is None: return {'message': u'克隆失败: 该数据中心下%s模版不存在' % template_name, 'result': False} # 获取宿主机 host = self.get_host_by_name(vm_exi_ip, datastore) if host is None: return {'message': u'克隆失败: 该存储下%s主机不存在' % vm_exi_ip, 'result': False} # 获取宿主机下的vm vms = host.vm for vm in vms: print("##host vm:", vm) config = vm.summary.config if vm_name == config.name: return {'message': u'克隆失败: 虚拟机%s曾经存在' % vm_name, 'result': False} # 获取资源池 resourcepool = host.parent.resourcePool relospec = vim.vm.RelocateSpec() relospec.datastore = datastore relospec.pool = resourcepool relospec.host = host # 配置Clone属性 clonespec = vim.vm.CloneSpec() clonespec.location = relospec clonespec.powerOn = True device_change = [] # # 设置网卡 # if len(template.network) == 0: # logging.info(u'设置网卡') # nic_change = self.add_nic('VM Network') # device_change.extend(nic_change) # 指定网络段配置 if vm_vlan: device_nic_change = self.device_nic( vm=template, network_name=vm_vlan, switch_type=switch_type ) device_change.extend(device_nic_change) # 批改硬盘大小 # vm_disk 必须比原来值大哦 if vm_disk: logging.info(u'扩容硬盘') disk_change = self.change_disk_size(template, vm_disk) if type(disk_change) is list: device_change.extend(disk_change) else: return {'message': disk_change, 'result': False} # add_disk if vm_add_disk: logging.info(u'扩容硬盘') add_disk_change = self.add_disk(template, vm_add_disk) if type(add_disk_change) is list: device_change.extend(add_disk_change) else: return {'message': add_disk_change, 'result': False} # 更新配置 vmconf = vim.vm.ConfigSpec(deviceChange=device_change) logging.info(u'更新网卡网卡的配置') # 设置IP if all([vm_ip, vm_subnetmask, vm_gateway]): clonespec.customization = self.get_customspec(vm_ip, vm_subnetmask, vm_gateway, vm_dns, vm_domain, vm_hostname) logging.info(u'设置IP') # 更改cpu和内存 if cup_num: vmconf.numCPUs = cup_num if memory: vmconf.memoryMB = memory * 1024 if vmconf is not None: clonespec.config = vmconf # 开始克隆 task = template.Clone(folder=vmfolder, name=vm_name, spec=clonespec) vm_task = { 'task': task, 'vm_name': vm_name, 'vm_ip': vm_ip, 'vm_exi_ip': vm_exi_ip } data = {'message': u'工作下发胜利', 'result': True, 'data': vm_task} return dataif __name__ == '__main__': ip = '10.31.1xx.4x' user = 'axxxxcal' password = 'Qxxxxx4' port = 443 template_name = u'centos7temp' vm_name = u'centos7test60' data_center_name = u'Datacenter' datastore_name = u'datastore1' cluster_name = "10.31.1xx.x6" host_name = "10.31.1x.x6" cup_num = 2 memory = 2 resource_pool = None power_on = True vm_ext_disk = 50 vm_add_disk = 20 vm_ip = '10.31.1xx.x8' vm_subnetmask = '255.255.255.0' vm_gateway = '10.31.1xx.1' vm_dns = '8.8.8.8' vm_vlan = None switch_type = None vm_domain = 'xiaohxx.com' vm_hostname = 'test' vm = VmManage(host=ip, user=user, password=password, port=port, ssl=None) data = vm.clone_host(template_name=template_name, vm_name=vm_name, datacenter_name=data_center_name, datastore_name=datastore_name, vm_exi_ip=host_name, vm_vlan=None, switch_type=None, vm_folder=None, cup_num=4, memory=2, vm_disk=None, vm_add_disk=30, vm_ip=vm_ip, vm_subnetmask=vm_subnetmask, vm_gateway=vm_gateway, vm_dns=vm_dns, vm_domain=vm_domain, vm_hostname=vm_hostname) # 给vm add 30G磁盘 #data = vm.add_disk_to_vm(vm_name=template_name, capacity=30) # # 虚拟机开机,期待x0秒,待虚拟机开机启动获取IP地址 # vm_obj = vm._get_obj([vim.VirtualMachine], vm_name) # task = vm_obj.PowerOn() # print("启动 VM 电源") # print(vm.wait_for_task(task)) # time.sleep(50) # print("开始获取 VM IP地址") # vm_obj_ip = vm.get_vm_ip(vm_obj) # # 虚拟机 off # vm_obj = vm._get_obj([vim.VirtualMachine], template_name) # task = vm_obj.PowerOff() # print("PowerOff") # print(vm.wait_for_task(task)) # time.sleep(20) # data = vm.clone_cluster( # template_name=template_name, # vm_name=vm_name, # datacenter_name=data_center_name, # cluster_name=cluster_name, # datastore_name=datastore_name, # host_name=host_name, # cup_num=cup_num, # memory=memory, # vm_ip=vm_ip, # vm_subnetmask=vm_subnetmask, # vm_gateway=vm_gateway, # vm_dns=vm_dns, # vm_domain=vm_domain, # vm_hostname=vm_hostname # ) print(data) ...

October 18, 2022 · 9 min · jiezi

关于python3.x:Python-urlencode和unquote函数使用实例解析

当url地址含有中文,或者参数有中文的时候,这个算是很失常了,然而把这样的url作为参数传递的时候(最常见的callback),须要把一些中文甚至'/'做一下编码转换。 所以对于一些中文或者字符,url不辨认的,则须要进行转换,转换后果如下: 一、urlencodeurllib库外面有个urlencode函数,能够把key-value这样的键值对转换成咱们想要的格局,返回的是a=1&b=2这样的字符串,比方: import urllib.parsevalues={}values['username']='02蔡彩虹'values['password']='ddddd?'url="http://www.baidu.com"data=urllib.parse.urlencode(values)print(data)# 输入:username=02%E8%94%A1%E5%BD%A9%E8%99%B9&password=ddddd%3F如果只想对一个字符串进行urlencode转换,怎么办?urllib提供另外一个函数:quote() import urllib.parses='长春's=urllib.parse.quote(s)print(s)# 输入:%E9%95%BF%E6%98%A5二、urldecode当urlencode之后的字符串传递过去之后,承受结束就要解码了——urldecode。urllib提供了unquote()这个函数,可没有urldecode()! s='%E5%B9%BF%E5%B7%9E's=urllib.parse.unquote(s)print(s)# 输入: 广州原文地址:https://www.jb51.net/article/...

September 6, 2022 · 1 min · jiezi

关于python3.x:Python入门系列九piptry-except用户输入字符串格式

pip蕴含模块所需的所有文件。 查看是否装置了PIP $ pip --version装置包 $ pip install package_name应用包 import package_name删除包 $ pip uninstall camelcase列出包 pip listTry Excepttry: print(x)except: print("An exception occurred")您能够依据须要定义任意数量的异样块,例如,如果您想为非凡类型的谬误执行非凡代码块 try: print(x)except NameError: print("Variable x is not defined")except: print("Something else went wrong")如果没有引发谬误,能够应用else关键字定义要执行的代码块 try: print("Hello")except: print("Something went wrong")else: print("Nothing went wrong")如果指定了finally块,则无论try块是否引发谬误,都将执行finally。 ry: print(x)except: print("Something went wrong")finally: print("The 'try except' is finished")这对于敞开对象和清理资源十分有用 try: f = open("demofile.txt") try: f.write("Lorum Ipsum") except: print("Something went wrong when writing to the file") finally: f.close()except: print("Something went wrong when opening the file")作为Python开发人员,如果呈现条件,您能够抉择抛出异样。 ...

August 25, 2022 · 1 min · jiezi

关于python3.x:Python入门系列四别再傻傻分不清列表元组字典集合的区别

四句话总结列表是一个有序且可更改的汇合,容许反复成员。元组是一个有序且不可更改的汇合,容许反复成员。汇合是一个无序、不可更改*且未索引的汇合,没有反复成员。字典是一个有序且可更改的汇合,没有反复成员。私有的局部获取长度,应用len()要确定列表中有多少项,请应用len()函数 thislist = ["apple", "banana", "cherry"]print(len(thislist))要确定一个元组有多少项,请应用len()函数 thistuple = ("apple", "banana", "cherry")print(len(thistuple))要确定一个汇合有多少项,请应用len()函数。 thisset = {"apple", "banana", "cherry"}print(len(thisset))要确定字典有多少项,请应用len()函数 thisdict = { "brand": "Ford", "model": "Mustang", "year": 1964, "year": 2020}print(len(thisdict))通过援用索引号来拜访列表项已编制索引,您能够通过援用索引号来拜访它们 thislist = ["apple", "banana", "cherry"]print(thislist[1])您能够通过援用方括号内的索引号来拜访元组项 thistuple = ("apple", "banana", "cherry")print(thistuple[1])是否存在指定项,请应用in关键字要确定列表中是否存在指定项,请应用in关键字 thislist = ["apple", "banana", "cherry"]if "apple" in thislist: print("Yes, 'apple' is in the fruits list")要确定元组中是否存在指定项,请应用in关键字 thistuple = ("apple", "banana", "cherry")if "apple" in thistuple: print("Yes, 'apple' is in the fruits tuple")查看汇合中是否有“香蕉” thisset = {"apple", "banana", "cherry"}print("banana" in thisset)要确定字典中是否存在指定的键,请应用in关键字 ...

August 20, 2022 · 3 min · jiezi

关于python3.x:运筹帷幄决胜千里Python310原生协程asyncio工业级真实协程异步消费任务调度实践

咱们始终都置信这样一种说法:协程是比多线程更高效的一种并发工作形式,它齐全由程序自身所管制,也就是在用户态执行,协程防止了像线程切换那样产生的上下文切换,在性能方面失去了很大的晋升。毫无疑问,这是颠扑不破的业界共识,是放之四海而皆准的真谛。 但事实上,协程远比大多数人设想中的简单,正因为协程的“用户态”个性,任务调度权把握在撰写协程工作的人手里,而仅仅依赖async和await关键字远远达不到“调度”的级别,有时候反而会连累工作效率,使其在工作执行效率上还不迭“零碎态”的多线程和多过程,本次咱们来探讨一下Python3原生协程工作的调度治理。 Python3.10协程库async.io的基本操作事件循环(Eventloop)是 原生协程库asyncio 的外围,能够了解为总指挥。Eventloop实例提供了注册、勾销和执行工作和回调的办法。 Eventloop能够将一些异步办法绑定到事件循环上,事件循环会循环执行这些办法,然而和多线程一样,同时只能执行一个办法,因为协程也是单线程执行。当执行到某个办法时,如果它遇到了阻塞,事件循环会暂停它的执行去执行其余的办法,与此同时为这个办法注册一个回调事件,当某个办法从阻塞中复原,下次轮询到它的时候将会继续执行,亦或者,当没有轮询到它,它提前从阻塞中复原,也能够通过回调事件进行切换,如此往返,这就是事件循环的简略逻辑。 而下面最外围的动作就是切换别的办法,怎么切换?用await关键字: import asyncio async def job1(): print('job1开始') await asyncio.sleep(1) print('job1完结') async def job2(): print('job2开始') async def main(): await job1() await job2() if __name__ == '__main__': asyncio.run(main())零碎返回: job1开始 job1完结 job2开始是的,切则切了,可切的对吗?事实上这两个协程工作并没有达成“合作”,因为它们是同步执行的,所以并不是在办法内await了,就能够达成协程的工作形式,咱们须要并发启动这两个协程工作: import asyncio async def job1(): print('job1开始') await asyncio.sleep(1) print('job1完结') async def job2(): print('job2开始') async def main(): #await job1() #await job2() await asyncio.gather(job1(), job2()) if __name__ == '__main__': asyncio.run(main())零碎返回: job1开始 job2开始 job1完结如果没有asyncio.gather的参加,协程办法就是一般的同步办法,就算用async申明了异步也杯水车薪。而asyncio.gather的根底性能就是将协程工作并发执行,从而达成“合作”。 但事实上,Python3.10也反对“同步写法”的协程办法: async def create_task(): task1 = asyncio.create_task(job1()) task2 = asyncio.create_task(job2()) await task1 await task2这里咱们通过asyncio.create\_task对job1和job2进行封装,返回的对象再通过await进行调用,由此两个独自的异步办法就都被绑定到同一个Eventloop了,这样尽管写法上同步,但其实是异步执行: ...

August 8, 2022 · 3 min · jiezi

关于python3.x:物无定味适口者珍Python3并发场景CPU密集IO密集任务的并发方式的场景抉择多线程多进程协程asyncio

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_221 个别状况下,大家对Python原生的并发/并行工作形式:过程、线程和协程的关系与区别都能讲清楚。甚至具体的对象名称、内置办法都能够一五一十,这显然是极好的,但咱们其实都疏忽了一个问题,就是具体利用场景,三者的应用目标是一样的,话句话说,应用后果是一样的,都能够进步程序运行的效率,但到底那种场景用那种形式更好一点? 这就好比,目前支流的汽车发动机变速箱无外乎三种:双离合、CVT以及传统AT。主机厂把它们搭载到不同的发动机和车型上,它们都是变速箱,都能够将发动机产生的能源作用到车轮上,但不同应用场景下到底该抉择那种变速箱?这显然也是一个问题。 所谓“无场景,不性能”,本次咱们来讨论一下,具体的并发编程场景有哪些,并且对应到具体场景,应该怎么抉择并发伎俩和形式。 什么是并发和并行?在探讨场景之前,咱们须要将多任务执行的形式进行一下分类,那就是并发形式和并行形式。教科书上通知咱们:并行是指两个或者多个事件在同一时刻产生;而并发是指两个或多个事件在同一时间距离内产生。 在多道程序环境下,并发性是指在一段时间内宏观上有多个程序在同时运行,但在单处理机零碎中,每一时刻却仅能有一道程序执行,故宏观上这些程序只能是分时地交替执行。 如同有那么一点形象,好吧,让咱们求实一点,因为GIL全局解释器锁的存在,在Python编程畛域,咱们能够简略粗犷地将并发和并行用程序通过是否应用多核CPU来辨别,能应用多核CPU就是并行,不能应用多核CPU,只能单核解决的,就是并发。就这么简略,是的,Python的GIL全局解释器锁帮咱们把问题简化了, 这是Python的大幸?还是可怜? Python中并发工作实现形式蕴含:多线程threading和协程asyncio,它们的共同点都是交替执行,而区别是多线程threading是抢占式的,而协程asyncio是合作式的,原理也很简略,只有一颗CPU能够用,而一颗CPU一次只能做一件事,所以只能靠不停地切换能力实现并发工作。 Python中并行任务的实现形式是多过程multiprocessing,通过multiprocessing库,Python能够在程序主过程中创立新的子过程。这里的一个过程能够被认为是一个简直齐全不同的程序,只管从技术上讲,它们通常被定义为资源汇合,其中资源包含内存、文件句柄等。换一种说法是,每个子过程都领有本人的Python解释器,因而,Python中的并行任务能够应用一颗以上的CPU,每一颗CPU都能够跑一个过程,是真正的同时运行,而不须要切换,如此Python就能够实现并行任务。 什么时候应用并发?IO密集型工作当初咱们搞清楚了,Python里的并发运行形式就是多线程threading和协程asyncio,那么什么场景下应用它们? 个别状况下,工作场景,或者说的更精确一些,工作类型,无非两种:CPU密集型工作和IO密集型工作。 什么是IO密集型工作?IO就是Input-Output的缩写,说白了就是程序的输出和输入,想一想的确就是这样,您的电脑,它不就是这两种性能吗?用键盘、麦克风、摄像头输出数据,而后再用屏幕和音箱进行输入操作。 但输出和输入操作要比电脑中的CPU运行速度慢,换句话说,CPU得等着这些比它慢的输出和输入操作,说白了就是CPU运算一会,就得等这些IO操作,等IO操作完了,CPU能力持续运算一会,而后再等着IO操作,如图所示: 由此可知,并发适宜这种IO操作密集和频繁的工作,因为就算CPU是苹果最新ARM架构的M2芯片,也没有用武之地。 另外,如果把IO密集型工作具象化,那就是咱们常常操作的:硬盘读写(数据库读写)、网络申请、文件的打印等等。 并发形式的抉择:多线程threading还是协程asyncio?既然波及硬盘读写(数据库读写)、网络申请、文件打印等工作都算并发工作,那咱们就真正地实际一下,看看不同的并发形式到底能晋升多少效率? 一个简略的小需要,对本站数据进行反复抓取操作,并计算首页数据文本的行数: import requests import time def download_site(url, session): with session.get(url) as response: print(f"下载了{len(response.content)}行数据") def download_all_sites(sites): with requests.Session() as session: for url in sites: download_site(url, session) if __name__ == "__main__": sites = ["https://v3u.cn"] * 50 start_time = time.time() download_all_sites(sites) duration = time.time() - start_time print(f"下载了 {len(sites)}次,执行了{duration}秒")在不应用任何并发伎俩的前提下,程序返回: 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了76347行数据 下载了 50 次数据,执行了8.781155824661255秒 [Finished in 9.6s]这里程序的每一步都是同步操作,也就是说当第一次抓取网站首页时,剩下的49次都在期待。 ...

August 1, 2022 · 3 min · jiezi

关于python3.x:日夕如是寒暑不间基于Python3Tornado6APSchedulerCelery打造并发异步动态定时任务轮询服务

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_220 定时工作的典型落地场景在各行业中都很广泛,比方领取零碎中,领取过程中因为网络或者其余因素导致呈现掉单、卡单的状况,账单变成了“单边账”,这种状况对于领取用户来说,毫无疑问是劫难级别的体验,明明本人付了钱,扣了款,然而订单状态却未发生变化。所以,每一笔订单的领取工作流程中都须要一个定时轮询的备选计划,一旦领取中产生问题,定时轮询服务就能够及时发现和更正订单状态。 又比方,之前的一篇以寡治众各个击破,超大文件分片上传之构建基于Vue.js3.0+Ant-desgin+Tornado6纯异步IO高效写入服务,在超大型文件分片传输工作过程中,一旦分片上传或者分片合并环节出了问题,就有可能导致超大型文件无奈残缺的传输到服务器中,从而节约大量的零碎带宽资源,所以每一个分片传输工作执行过程中也须要一个对应的定时轮询来“盯”着,避免过程中呈现问题。 在理论业务场景中,定时服务根本都作为主利用的从属服务而存在,不同定时工作的调度工夫可能不一样,所以如果可能配合主服务并发异步调用定时工作,则能够单利用可能反对上万,甚至十万以上的定时工作,并且不同工作可能有独立的调度工夫,这里通过Tornado配合APScheduler和Celery,别离展现不同的异步定时工作调用逻辑。 APSchedulerAPScheduler(advanceded python scheduler)是一款及其优良的Python3定时工作框架,它不仅反对并发异步调用定时工作,还能够动静地对定时工作进行治理,同时也反对定时工作的长久化。 首先装置APScheduler以及Tornado6: pip3 install apschedulerpip3 install tornado==6.1随后导入基于Tornado的异步APScheduler: from datetime import datetime from tornado.ioloop import IOLoop, PeriodicCallback from tornado.web import RequestHandler, Application from apscheduler.schedulers.tornado import TornadoScheduler这里TornadoScheduler实例就具备了Tornado的事件循环个性,随后申明异步定时工作: async def task(): print('[APScheduler][Task]-{}'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')))随后初始化定时工作对象: scheduler = None # 初始化 def init_scheduler(): global scheduler scheduler = TornadoScheduler() scheduler.start() scheduler.add_job(task,"interval",seconds=3,id="job1",args=()) print("定时工作启动")这里启动后就增加一个定时工作,每隔三秒执行一次。 接着main入口启动服务: if __name__ == '__main__': init_scheduler()零碎返回: C:\Users\liuyue\www\tornado6>python test_scheduler.py 定时工作启动 [APScheduler][Task]-2022-07-28 22:13:47.792582 [APScheduler][Task]-2022-07-28 22:13:50.783016 [APScheduler][Task]-2022-07-28 22:13:53.783362 [APScheduler][Task]-2022-07-28 22:13:56.775059 [APScheduler][Task]-2022-07-28 22:13:59.779563随后创立Tornado控制器视图: ...

July 28, 2022 · 4 min · jiezi

关于python3.x:python字符串拼接

err = '错误信息'str1 = f'error:{err}'str2 = 'error:{}'.format(err)str3 = 'error:' + errprint(str1)print(str2)print(str3)输入error:错误信息error:错误信息error:错误信息

July 5, 2022 · 1 min · jiezi

关于python3.x:从开发属于你自己的第一个-Python-库做一名真正的程序员双语版

你好,我是悦创。之前我在 CSDN 编写了一篇开发 Python 库的教程,有人加我发问到的一些问题,我来更新一下这篇文章:https://blog.csdn.net/qq_33254766/article/details/119874997 新版文章首发:https://bornforthis.cn/posts/18.html 你好,我是悦创。 Hello, I'm Yue Chuang.我最近想要去开始开发 Python 第三方库,然而发现国内这样的教程太少了,所以就我来写吧! I recently wanted to start developing Python third-party libraries, but found that there are too few such tutorials in the country, so I will write them instead!还有就是已经想创立一个 Python 库,无论是为您的工作团队还是在线的一些开源我的项目?在此博客中,您将学习如何操作! Ever wanted to create a Python library, albeit for your team at work or for some open source project online? In this blog you will learn how to!当您应用雷同的开发工具 Pycharm ,你会最容易跟上我的教程,当然您也能够应用不同的工具。 ...

June 28, 2022 · 10 min · jiezi

关于python3.x:亲妈版Python批量将PPT转换为PPTX

前言:本文基于Python语言环境实现,以及vsCode工具开发实现,能够反对ppt转pptx 或 pptx转ppt pdf png 等格局。 正式开发:1、装置reportlab模块#装置reportlab模块pip3 install reportlab2、装置win32com模块第一种: pip3 install pywin32第二种: python -m pip install --upgrade pip -i https://pypi.douban.com/simple3、创立pptToPptx.pyimport osimport loggingfrom reportlab.lib.pagesizes import A4, landscapefrom reportlab.pdfgen import canvasimport win32com.clientlogger = logging.getLogger('Sun')logging.basicConfig(level=20, # format="[%(name)s][%(levelname)s][%(asctime)s] %(message)s", format="[%(levelname)s][%(asctime)s] %(message)s", datefmt='%Y-%m-%d %H:%M:%S' # 留神月份和天数不要搞乱了,这里的格式化符与time模块雷同 )def getFiles(dir, suffix, ifsubDir=True): # 查找根目录,文件后缀 res = [] for root, directory, files in os.walk(dir): # =>以后根,根下目录,目录下的文件 for filename in files: name, suf = os.path.splitext(filename) # =>文件名,文件后缀 if suf.upper() == suffix.upper(): res.append(os.path.join(root, filename)) # =>吧一串字符串组合成门路 if False is ifsubDir: break return resclass pptTrans: def __init__(self, infoDict, filePath): self.infoDict = infoDict self.filePath = filePath self.powerpoint = None self.init_powerpoint() self.convert_files_in_folder(self.filePath) self.quit() os.system('pause') def quit(self): if None is not self.powerpoint: self.powerpoint.Quit() def init_powerpoint(self): try: self.powerpoint = win32com.client.DispatchEx("Powerpoint.Application") self.powerpoint.Visible = 2 except Exception as e: logger.error(str(e)) def ppt_trans(self, inputFileName): # https://docs.microsoft.com/en-us/office/vba/api/powerpoint.ppsaveasfiletype infoDict = self.infoDict formatType = infoDict['formatType'] outputFileName = self.getNewFileName(infoDict['name'], inputFileName) if '' == outputFileName: return inputFileName = inputFileName.replace('/', '\\') outputFileName = outputFileName.replace('/', '\\') if '' == outputFileName: return if None is self.powerpoint: return powerpoint = self.powerpoint logger.info('开始转换:[{0}]'.format(inputFileName)) deck = powerpoint.Presentations.Open(inputFileName) try: deck.SaveAs(outputFileName, formatType) # formatType = 32 for ppt to pdf logger.info('转换实现:[{0}]'.format(outputFileName)) except Exception as e: logger.error(str(e)) deck.Close() def convert_files_in_folder(self, filePath): if True is os.path.isdir(filePath): dirPath = filePath files = os.listdir(dirPath) pptfiles = [f for f in files if f.endswith((".ppt", ".pptx"))] elif True is os.path.isfile(filePath): pptfiles = [filePath] else: self.logError('不是文件夹,也不是文件') return for pptfile in pptfiles: fullpath = os.path.join(filePath, pptfile) self.ppt_trans(fullpath) def getNewFileName(self, newType, filePath): try: dirPath = os.path.dirname(filePath) baseName = os.path.basename(filePath) dirPath += "/pptx" fileName = baseName.rsplit('.', 1)[0] suffix = baseName.rsplit('.', 1)[1] if newType == suffix: logger.warning('文档[{filePath}]类型和须要转换的类型[{newType}]雷同'.format(filePath=filePath, newType=newType)) return '' newFileName = '{dir}/{fileName}.{suffix}'.format(dir=dirPath, fileName=fileName, suffix=newType) if os.path.exists(newFileName): newFileName = '{dir}/{fileName}_new.{suffix}'.format(dir=dirPath, fileName=fileName, suffix=newType) return newFileName except Exception as e: logger.error(str(e)) return ''class pngstoPdf: def __init__(self, infoDict, filePath): self.infoDict = infoDict self.powerpoint = None self.init_powerpoint() self.convert_files_in_folder(filePath) self.quit() os.system('pause') def quit(self): if None is not self.powerpoint: self.powerpoint.Quit() def init_powerpoint(self): try: self.powerpoint = win32com.client.DispatchEx("Powerpoint.Application") self.powerpoint.Visible = 2 except Exception as e: logger.error(str(e)) def ppt_trans(self, inputFileName): # https://docs.microsoft.com/en-us/office/vba/api/powerpoint.ppsaveasfiletype infoDict = self.infoDict formatType = infoDict['formatType'] outputFileName = self.getNewFolderName(inputFileName) if '' == outputFileName: return '' inputFileName = inputFileName.replace('/', '\\') outputFileName = outputFileName.replace('/', '\\') if '' == outputFileName: return '' if None is self.powerpoint: return '' powerpoint = self.powerpoint logger.info('开始转换:[{0}]'.format(inputFileName)) deck = powerpoint.Presentations.Open(inputFileName) try: deck.SaveAs(outputFileName, formatType) logger.info('转换实现:[{0}]'.format(outputFileName)) except Exception as e: logger.error(str(e)) return '' deck.Close() return outputFileName def convert_files_in_folder(self, filePath): if True is os.path.isdir(filePath): dirPath = filePath files = os.listdir(dirPath) pptfiles = [f for f in files if f.endswith((".ppt", ".pptx"))] elif True is os.path.isfile(filePath): pptfiles = [filePath] else: self.logError('不是文件夹,也不是文件') return for pptfile in pptfiles: fullpath = os.path.join(filePath, pptfile) folderName = self.ppt_trans(fullpath) try: self.png_to_pdf(folderName) except Exception as e: logger.error(str(e)) for file in os.listdir(folderName): os.remove('{0}\\{1}'.format(folderName, file)) os.rmdir(folderName) def png_to_pdf(self, folderName): picFiles = getFiles(folderName, '.png') pdfName = self.getFileName(folderName) '''多个图片合成一个pdf文件''' (w, h) = landscape(A4) # cv = canvas.Canvas(pdfName, pagesize=landscape(A4)) for imagePath in picFiles: cv.drawImage(imagePath, 0, 0, w, h) cv.showPage() cv.save() def getFileName(self, folderName): dirName = os.path.dirname(folderName) folder = os.path.basename(folderName) return '{0}\\{1}.pdf'.format(dirName, folder) def getNewFolderName(self, filePath): index = 0 try: dirPath = os.path.dirname(filePath) baseName = os.path.basename(filePath) fileName = baseName.rsplit('.', 1)[0] newFileName = '{dir}/{fileName}'.format(dir=dirPath, fileName=fileName) while True: if os.path.exists(newFileName): newFileName = '{dir}/{fileName}({index})'.format(dir=dirPath, fileName=fileName, index=index) index = index + 1 else: break return newFileName except Exception as e: logger.error(str(e)) return ''if __name__ == "__main__": transDict = {} transDict.update({1: {'name': 'pptx', 'formatType': 11}}) transDict.update({2: {'name': 'ppt', 'formatType': 1}}) transDict.update({3: {'name': 'pdf', 'formatType': 32}}) transDict.update({4: {'name': 'png', 'formatType': 18}}) transDict.update({5: {'name': 'pdf(不可编辑)', 'formatType': 18}}) hintStr = '' for key in transDict: hintStr = '{src}{key}:->{type}\n'.format(src=hintStr, key=key, type=transDict[key]['name']) while True: print(hintStr) transFerType = int(input("转换类型:")) if None is transDict.get(transFerType): logger.error('未知类型') else: infoDict = transDict[transFerType] path = input("文件门路:") if 5 == transFerType: pngstoPdf(infoDict, path) else: op = pptTrans(infoDict, path)4、运行Py文件第一种:cmd运行找到文件目录输出:python pptToPptx.py ...

June 24, 2022 · 3 min · jiezi

关于python3.x:python调试报错-greenleterror-cannot-switch-to-a-different-thread

解决办法File->settings->build->python debugger->gevent compatible(勾选)

June 11, 2022 · 1 min · jiezi

关于python3.x:520专属Python代码分享

快到 520 了,分享几段 520 专属 Python 代码,不多说了,上面间接上货。 No.1成果:次要代码: import turtleturtle.speed(0)turtle.delay(10)turtle.penup()turtle.left(90)turtle.fd(200)turtle.pendown()turtle.right(90)turtle.fillcolor('red')turtle.begin_fill()turtle.circle(10, 180)turtle.circle(25, 110)turtle.left(50)turtle.circle(60, 45)turtle.circle(20, 170)turtle.right(24)turtle.fd(30)turtle.left(10)# 花瓣turtle.left(150)turtle.circle(-90, 70)turtle.left(20)turtle.circle(75, 105)turtle.setheading(60)turtle.circle(80, 98)turtle.circle(-90, 40)# 文字turtle.color('red')turtle.pu()turtle.goto(-210,80)turtle.pd()turtle.write('520 Happy', move=False, align='center',font=("Times", 18, "bold"))turtle.pu()turtle.goto(210,80)turtle.pd()turtle.write('I LOVE YOU', move=False, align='center',font=("Times", 18, "bold"))turtle.pu()turtle.pu()turtle.hideturtle()turtle.done()No.2成果:次要代码: import turtle as tt.speed(0)t.delay(10)t.color('red','pink')t.begin_fill()t.width(5)t.left(135)t.fd(100)t.right(180)t.circle(50,-180)t.left(90)t.circle(50,-180)t.right(180)t.fd(100)t.pu()t.goto(50,-30)# 箭头t.begin_fill()t.left(-30)t.fd(-15)t.right(-40)t.fd(-50)t.right(-165)t.fd(-50)t.end_fill()# 文字t.color('red')t.pu()t.goto(-150,30)t.pd()t.write('I LOVE YOU',move=False, align='center',font=("Times", 18, "bold"))t.hideturtle()t.done()No.3成果:次要代码: import turtleimport random# 画爱心def love(x, y): lv = turtle.Turtle() lv.hideturtle() lv.up() # 定位 lv.goto(x, y) # 画圆弧 def curvemove(): for i in range(20): lv.right(10) lv.forward(2) lv.color('red', 'pink') lv.speed(10000000) lv.pensize(1) lv.down() lv.begin_fill() lv.left(140) lv.forward(22) curvemove() lv.left(120) curvemove() lv.forward(22) # 画完复位 lv.left(140) lv.end_fill()myWin = turtle.Screen()myWin.setup(width=700, height=700)t = turtle.Turtle()t.speed(0)turtle.delay(0)t.hideturtle()t.left(90)t.up()t.backward(200)t.down()t.color("brown")t.pensize(32)t.forward(60)tree(100, t)myWin.exitonclick() 源码在公众号Python小二后盾回复py520获取~ ...

May 16, 2022 · 1 min · jiezi

关于python3.x:Python语言重要知识点梳理二字符串常用操作极其详细

75.字符串的创立与驻留机制字符串 在Python中字符串是根本数据类型,是一个不可变的字符序列什么叫字符串驻留机制呢?仅保留一份雷同且不可变字符串的办法,不同的值被寄存在字符串的驻留池中,Python的驻留机制对雷同的字符串只保留一份拷贝,后续创立雷同字符串时,不会开拓新空间,而是把该字符串的地址赋给新创建的变量 #实例a='Python'b="Python"c='''Python'''print(a,id(a)) #输入变量a,查看id地址print(b,id(b))print(c,id(c)) 驻留机制的几种状况(交互模式) 字符串的长度为0或1时合乎标识符的字符串字符串只在编译时进行驻留,而非运行时[-5,256]之间的整数数字sys中的intern办法强制2个字符串指向同一个对象 PyCharm对字符串进行了优化解决关上Python交互式进行测试字符串的长度为0或1时合乎标识符的字符串 上面这个就是合乎标识符的字符串了,能够看到id内存地址均为3424字符串只在编译时进行驻留,而非运行时 python是一种解释型语言,但实际上它的解释器也能够了解成编译器,它负责将python代码编译成字节码,也就是.pyc文件,  [-5,256]之间的整数数字 字符串驻留机制的优缺点 当须要值雷同的字符串时,能够间接从字符串池里拿来应用,防止频繁的创立和销毁,晋升效率和节约内存,因而拼接字符串和批改字符串是会比拟影响性能的。在须要进行字符串拼接时倡议应用str类型的join办法,而非+,因为join()办法是先计算出所有字符中的长度,而后再拷贝,只new一次对象,效率要比"+"效率高 76.字符串的罕用操作_字符串的查问操作能够把字符串看成是字符的列表,所以字符串与列表查的操作是十分类似的,但区别就在于,当取得字符串中指定的索引时,除了有Index外,还有rindex、find以及rfind办法,#实例s='hello,hello'print(s.index('lo')) #运行后果3print(s.find('lo')) #运行后果3print(s.rindex('lo')) #运行后果9print(s.rfind('lo')) #运行后果9 #实例#print(s.index('k')) #运行后果为ValueError: substring not found 译文:子串没找到print(s.find('k')) #运行后果为-1 -->-->查找最初一次呈现的地位,不存在返回-1;倡议用不抛异样这种办法#print(s.rindex('k')) #运行后果为SyntaxError: unexpected EOF while parsing 译文:解析时出现意外print(s.rfind('k')) #运行后果为-1 -->查找最初一次呈现的地位,不存在返回-177.字符串的罕用操作_字符串的大小写转换操作方法 #实例print('---字符串中的大小写转换的办法---')s='hello,python'a=s.upper() #转大写后会产生一个新的字符串对象(艰深讲就是会增加一个内存空间,内存地址会变)print(a,id(a)) #转换后;运行后果为HELLO,PYTHON 2969352950256print(s,id(s)) #转换前;运行后果为hello,python 2969352985584b=s.lower() #转换后会产生一个新的字符串对象print(b,id(b)) #运行后果为hello,python 1939784160688print(s,id(s)) #运行后果为hello,python 1939783867376print(b==s) #内容雷同print(b is a) #运行后果为false,也就是说内容是雷同的,内存地址不同,没有字符串驻留机制#print(s.lower(),id(s.lower()))#print(s,id(s))s2='hello,Python'print(s2.swapcase()) #运行后果为HELLO,pYTHON -->小写转大写,大写转小写print(s2.title()) #运行后果为Hello,Python -->每个单词首字母都转大写,其它都转小写78.字符串的罕用操作_字符串内容对齐操作的办法 #实例(很像文档中的左对齐、居中对齐、右对齐)s='hello.Python' #申明一个变量print('---居中对齐.center()---')print(s.center(20,'*')) #运行后果为****hello.Python**** -->设置s变量的字符串为居中20个字符,hello,Python为12个字符,20-12=8因而指定星号*为两侧填充内容print('---左对齐.ljust()---')print(s.ljust(20,'*')) #print(s.ljust(10)) #运行后果为hello.Python -->设置参数小于字符串字符长度且不指定第二个参数,将返回原字符print(s.ljust(20)) #运行后果为hello.Python -->不指定第二个参数,输入后果前面是相应的空格print('---右对齐.rjust()---')print(s.rjust(20,'*')) #运行后果为********hello.Pythonprint(s.rjust(20)) #运行后果为 hello.Pythonprint(s.rjust(10)) #运行后果为hello.Pythonprint('---右对齐.zfill() 应用0进行填充---')print(s.zfill(20))print(s.zfill(10))print('-8910'.zfill(8))#运行后果---居中对齐.center()---****hello.Python****---左对齐.ljust()---hello.Python********hello.Pythonhello.Python ---右对齐.rjust()---********hello.Python hello.Pythonhello.Python---右对齐.zjust() 应用0进行填充---00000000hello.Pythonhello.Python-000891079.字符串的罕用操作_字符串的劈分 ...

May 14, 2022 · 1 min · jiezi

关于python3.x:Python-运算符重载

Python 运算符重载 class MyComplex: def __init__(self, _real, _imag): self.real = _real self.imag = _imag def __add__(self, comp): if type(self) is type(comp): return MyComplex(self.real+comp.real, self.imag+comp.imag) else: return MyComplex(self.real+comp, self.imag) def __sub__(self, comp): if type(self) is type(comp): return MyComplex(self.real-comp.real, self.imag-comp.imag) else: return MyComplex(self.real-comp, self.imag) def __mul__(self, comp): if type(self) is type(comp): return MyComplex(self.real*comp.real-self.imag*comp.imag, self.real*comp.imag+self.imag*comp.real) else: return MyComplex(self.real*comp, self.imag*comp) def __str__(self): if self.imag>=0: return f'{self.real}+{self.imag}i' else: return f'{self.real}{self.imag}i'def main(): c1 = MyComplex(3,-5) c2 = MyComplex(2,3) print(c1,c2) print('c1+c2=', c1+c2) print('c1-c2=', c1-c2) print('c1*c2=', c1*c2)if __name__=="__main__": main()

May 8, 2022 · 1 min · jiezi

关于python3.x:python中else的三种用法

python中else能够在判断语句、循环语句和异样解决中应用。 判断语句 if ... else ...a = 3b = 2if a > b: print("a大于b")else: print("b比a大")循环语句 for/while ... else ...当循环中未执行break语句即循环体失常完结则执行else语句,如果循环中执行了break则不执行else语句 for循环elsefor i in range(3): print(i)else: print("循环执行完")输入 012循环执行完for i in range(3): print(i) breakelse: print('循环失常执行完')输入 0应用场景:质数判断 for num in range(10, 20): for i in range(2, num): if num % i == 0: j = num / i print("%d 等于 %d * %d" % (num, i, j)) break else: print(num, '是一个质数')输入 10 等于 2 * 511 是一个质数12 等于 2 * 613 是一个质数14 等于 2 * 715 等于 3 * 516 等于 2 * 817 是一个质数18 等于 2 * 919 是一个质数while循环count = 0while count < 5: print("%d is less than 5" % count) count += 1else: print("%d is not less than 5" % count)输入 ...

April 17, 2022 · 1 min · jiezi

关于python3.x:python-ldap查询用户

LDAP_SERVER_POOL = "ldap://10.x1.x0.x1:389"ADMIN_DN = "CN=it_ldap,OU=ServiceAccount,DC=xxxxhu,DC=sh" ##ldap治理用户ADMIN_PASSWORD = "uxxzP"SEARCH_BASE = "OU=xixoxxhu-sh,DC=xxxshu,DC=sh"import ldapldapconn = ldap.initialize(LDAP_SERVER_POOL)print(ldapconn.simple_bind_s(ADMIN_DN, ADMIN_PASSWORD))searchScope = ldap.SCOPE_SUBTREE#searchFilter = 'sAMAccountName=lixxxx'searchFilter = 'cn=李xx'print(ldapconn.search_s(SEARCH_BASE, searchScope, searchFilter, None))呈现 (97, [], 1, []) 代表连贯胜利

April 13, 2022 · 1 min · jiezi

关于python3.x:python-opencv找不到Trackercreate的解决办法

opencv 4.x版本在应用Tracker_create等Tracker*办法时,可能会呈现"module 'cv2.cv2' has no attribute 'Tracker_create'"的问题,这时装置opencv-contrib-python即可解决: pip install opencv-contrib-python切记是pip不是pip3,如果不起作用就卸载opencv-contrib-python重装。

April 7, 2022 · 1 min · jiezi

关于python3.x:python3-使用influxdb12

import jsonimport datetimeimport requests, osfrom influxdb import InfluxDBClientDataBasename = "test"conn_db = InfluxDBClient('10.26.5.35', '8086', 'lixx', '12xx456', DataBasename)#conn_db.create_database('testdb') #创立数据库print(conn_db.get_list_database()) #显示所有数据库名称#conn_db.drop_database('testdb') #删除数据库#print("##test delet after:", conn_db.get_list_database())json_body = [ { "measurement": "ipad_electricitytable", "tags": { "ip": "10.31.140.24", "device_id": "sn:222ss222test", "device_type": "ipad" }, "fields": {"electricity": 79} }]conn_db.write_points(json_body) #写入数据,同时创立表result = conn_db.query('select * from ipad_electricitytable;') ##selectprint("Result: {0}".format(result))#conn_db.query('drop measurement students') #删除表result = conn_db.query("show measurements") #显示数据库中的表print("Result: {0}".format(result))#5、更新#tags和timestamp雷同时数据会笼罩操作,相当于influxDB的更新操作#6、删除#应用influxql语句实现,delete语法,示例如下"#conn_db.query('delete from ipad_electricitytable;') #删除数据

April 6, 2022 · 1 min · jiezi

关于python3.x:腾讯会议api-接口python3调用

# -- coding:utf-8 --import requestsimport hmacimport base64import hashlibimport timeimport randomimport json########test ############# AppId = '21dd1xx10'# SdkId = '1111140xx326'# SecretID = '5vE111111x11111RnBK83'# SecretKey = 'HkQa111111111111111qFNx9gETo'#########pro ##############AppId = '210x111x1119'SdkId = '1811111x1147'SecretID = 'qxF1111xxxxxxxxx9OUfxxxxxxg'SecretKey = 'xxxpFxxxwInDpVRxxxxxxXVQRbTN477'def get_sign(method, uri, Params, Nonce1, Time1): headerString = "X-TC-Key=" + SecretID + "&X-TC-Nonce=" + Nonce1 + "&X-TC-Timestamp=" + Time1 data = method + "\n" + headerString + "\n" + uri + "\n" + Params data = bytes(data.encode('utf-8')) key = SecretKey.encode('utf-8') return (base64.b64encode((hmac.new(key, data, digestmod=hashlib.sha256).hexdigest()).encode('utf-8'))).decode( 'utf-8')def CrateWrok(): uri = '/v1/meetings' Params = json.dumps({ "userid": "liyao", "instanceid": 1, "subject": "tester's meeting", "type": 0, "start_time": "1646200421", "end_time": "1646204021" }) Signature = get_sign('POST', uri, Params) Headers['X-TC-Signature'] = Signature GetData = requests.post("https://api.meeting.qq.com" + uri, headers=Headers, data=Params) print(GetData.json()) print(Headers)# 获取开课列表def GetWorkList(): uri = "/v1/meetings?userid=admin&instanceid=1" Signature = get_sign('GET', uri, Params='') Headers['X-TC-Signature'] = Signature GetData = requests.get("https://api.meeting.qq.com" + uri, headers=Headers) print(GetData.json())#user listdef GetuserList1(pagev, page_sizev): TodyTime = str(int(time.time())) Nonce = str(int(random.random() * 10000)) Headers = { "X-TC-Key": SecretID, "X-TC-Timestamp": TodyTime, "X-TC-Nonce": Nonce, "X-TC-Signature": '', "AppId": AppId, "SdkId": SdkId, "X-TC-Registered": "1" } uri = "/v1/users/list?page={tpagev}&page_size={tpage_sizev}".format(tpage_sizev=page_sizev, tpagev=pagev) Signature = get_sign('GET', uri, Params='', Nonce1=Nonce, Time1=TodyTime) Headers['X-TC-Signature'] = Signature GetData = requests.get("https://api.meeting.qq.com" + uri, headers=Headers) #print(GetData.json()) data_count = GetData.json() return data_count['total_count']#room listdef GetRoomList(pagev, page_sizev, meeting_room_namev): TodyTime = str(int(time.time())) Nonce = str(int(random.random() * 10000)) Headers = { "X-TC-Key": SecretID, "X-TC-Timestamp": TodyTime, "X-TC-Nonce": Nonce, "X-TC-Signature": '', "AppId": AppId, "SdkId": SdkId, "X-TC-Registered": "1" } uri = "/v1/meeting-rooms?page={page}&page_size={page_size}&meeting_room_name={meeting_room_name}".format( meeting_room_name=meeting_room_namev, page_size=page_sizev, page=pagev) Signature = get_sign('GET', uri, Params='', Nonce1=Nonce, Time1=TodyTime) Headers['X-TC-Signature'] = Signature GetData = requests.get("https://api.meeting.qq.com" + uri, headers=Headers) #print(GetData.json()) data_count = GetData.json() return data_count['total_count']#查问账户下 Rooms 资源def GetRoominventory(): TodyTime = str(int(time.time())) Nonce = str(int(random.random() * 10000)) Headers = { "X-TC-Key": SecretID, "X-TC-Timestamp": TodyTime, "X-TC-Nonce": Nonce, "X-TC-Signature": '', "AppId": AppId, "SdkId": SdkId, "X-TC-Registered": "1" } uri = "/v1/rooms-inventory" Signature = get_sign('GET', uri, Params='', Nonce1=Nonce, Time1=TodyTime) Headers['X-TC-Signature'] = Signature GetData = requests.get("https://api.meeting.qq.com" + uri, headers=Headers) #print(GetData.json()) return GetData.json() ...

March 22, 2022 · 2 min · jiezi

关于python3.x:并发异步编程之争协程asyncio到底需不需要加锁线程协程安全挂起主动切换Python3

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_208 协程与线程向来焦孟不离,但事实上是,线程更被咱们所熟知,在Python编程畛域,单核同工夫内只能有一个线程运行,这并不是什么缺点,这实际上是合乎主观逻辑的,单核处理器原本就没法同时解决两件事件,要同时进行多件事件原本就须要正在运行的让出处理器,而后能力去解决另一件事件,左手画方右手画圆在事实中原本就不成立,只不过这个让出的过程是线程调度器被动抢占的。 线程平安零碎的线程调度器是假如不同的线程是毫无关系的,所以它均匀地调配工夫片让处理器厚此薄彼,雨露均沾。然而Python受限于GIL全局解释器锁,任何Python线程执行前,必须先取得GIL锁,而后,每执行100条字节码,解释器就主动开释GIL锁,让别的线程有机会执行。这个GIL全局解释器锁实际上把所有线程的执行代码都给上了锁,所以,多线程在Python中只能交替执行,即便多个线程跑在8核解决上,也只能用到1个核。 但其实,这并不是事件的全貌,就算只能用单核解决工作,多个线程之前也并不是齐全独立的,它们会操作同一个资源。于是,大家又创造了同步锁,使得一段时间内只有一个线程能够操作这个资源,其余线程只能期待: import threading balance = 0 def change_it_without_lock(n): global balance # 不加锁的话 最初的值不是0 # 线程共享数据危险在于 多个线程同时改同一个变量 # 如果每个线程按程序执行,那么值会是0, 然而线程时系统调度,又不确定性,交替进行 # 没锁的话,同时批改变量 # 所以加锁是为了同时只有一个线程再批改,别的线程表肯定不能改 for i in range(1000000): balance = balance + n balance = balance - n def change_it_with_lock(n): global balance if lock.acquire(): try: for i in range(1000000): balance = balance + n balance = balance - n # 这里的finally 避免中途出错了,也能开释锁 finally: lock.release() threads = [ threading.Thread(target=change_it_with_lock, args=(8, )), threading.Thread(target=change_it_with_lock, args=(10, )) ] lock = threading.Lock() [t.start() for t in threads] [t.join() for t in threads] print(balance)这种异步编程形式被宽广开发者所认可,线程并不平安,线程操作共享资源须要加锁。然而人们很快发现,这种解决形式是在画龙点睛,处理器原本同一时间就只能有一个线程在运行。是线程调度器抢占划分工夫片给其余线程跑,而当初,多了把锁,其余线程又说我拿不到锁,我得拿到锁能力操作。 ...

March 18, 2022 · 2 min · jiezi

关于python3.x:我的第一个爬虫项目博客园爬虫CnblogsSpider

一、我的项目介绍、开发工具及环境配置1.1 我的项目介绍博客园爬虫次要针对博客园的新闻页面进行爬取数据并入库。上面是操作步骤:1、在关上新闻页面后,对其列表页数据的题目(含文本和链接)、图案(含图片和图片链接)、各个标签进行爬取。2、依据深度优先遍历原理,再依据列表页的题目链接进行下一步深刻,爬取外面的题目、注释、公布工夫、类别标签(后面这些说的都是动态页面的爬取)和阅读数、评论数、同意数(也叫举荐数)(前面这些说的都是基于动静网页技术的)。3、设计表构造,也即编辑字段和字段类型。同时编写入库函数,进行数据入库。1.2 开发工具Pycharm2019.3Navicat for MySQL11.1.131.3 环境配置应用命令行,cd到你想搁置的虚拟环境(virtualenv)的门路下,输出pip install virtualenv这时就装置好虚拟环境了,上面咱们将用指定的python3.6版本配置新我的项目的虚拟环境。 mkvirtualenv -p D:\Python36-64_install_location\python.exe article_spider其中,D:\Python36-64_install_location\是python3.6的装置门路,article_spider是新我的项目的虚拟环境名。上面要想进入虚拟环境(article_spider),输出workon article_spider进入虚拟环境后,因为某些python开发包在下载过程中会呈现timeout或很慢的状况,所以咱们应用python的豆瓣镜像,上面下载python爬虫框架scrapy: pip install -i https://pypi.douban.com/simple/ scrapy当然,有些时候Windows的某些零碎下会装置出错,这时登录以下网址:https://www.lfd.uci.edu/~gohl...这外面寄存了所有Windows下容易出错的开发包,快捷键Ctrl+F疾速搜寻须要的安装包,下载,下载好了当前,调出命令行,cd到下载好的门路下,输出 pip install -i https://pypi.douban.com/simple 下载好的文件名称(蕴含后缀)把握以上两种pip install形式基本上就能够搞定所有python开发包的装置。二、数据库设计数据库蕴含这些字段:题目,网址,网址Id,缓存图片门路,图片URL,点赞数,评论数,阅读数,标签,内容,公布日期字段类型如下: 编号字段名称数据类型是否为主键阐明1Titlevarchar(255)否题目2Urlvarchar(500)否网址3Url_object_idvarchar(50)是网址的Id4Front_image_pathvarchar(200)否缓存图片门路5Front_image_urlvarchar(500)否图片URL6Praise_numsInt(11)否点赞数7Comment_numsInt(11)否评论数8Fav_numsInt(11)否阅读数9Tagsvarchar(255)否标签10Contentlongtext否内容11Create_datedatetime否公布日期三、代码实现在main函数里设置增加爬虫(爬虫名字叫cnblogs)的文件门路和执行开始基于scrapy框架的爬虫命令: import sysimport osfrom scrapy.cmdline import execute # 执行scrapy的命令if __name__ == '__main__': sys.path.append(os.path.dirname(os.path.abspath(__file__))) execute(["scrapy","crawl","cnblogs"])到cnblogs.py(留神这里的文件名要与main外面对应的爬虫名一样)里编写外围代码: import reimport jsonimport scrapyfrom urllib import parsefrom scrapy import Requestfrom CnblogsSpider.utils import commonfrom CnblogsSpider.items import CnblogsArticleItem, ArticleItemLoaderclass CnblogsSpider(scrapy.Spider): name = 'cnblogs' allowed_domains = ['news.cnblogs.com'] # allowed_domains域名,也即容许的范畴 start_urls = ['http://news.cnblogs.com/'] # 启动main,进入爬虫,start_urls的html就下载好了 custom_settings = { # 笼罩settings以避免其余爬虫被追踪 "COOKIES_ENABLED":True } def start_requests(self): # 入口能够模仿登录拿到cookie import undetected_chromedriver.v2 as uc browser=uc.Chrome() #主动启动Chrome browser.get("https://account.cnblogs.com/signin") input("回车持续:") cookies=browser.get_cookies() # 拿到cookie并转成dict cookie_dict={} for cookie in cookies: cookie_dict[cookie['name']]=cookie['value'] for url in self.start_urls: headers ={ 'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.81 Safari/537.36' } # 设置headers进一步避免浏览器辨认出爬虫程序 yield scrapy.Request(url, cookies=cookie_dict, headers=headers, dont_filter=True) # 将cookie交给scrapy # 以上是模仿登录代码 def parse(self, response): url = response.xpath('//div[@id="news_list"]//h2[@class="news_entry"]/a/@href').extract_first("") post_nodes = response.xpath('//div[@class="news_block"]') # selectorlist for post_node in post_nodes: # selector image_url = post_node.xpath('.//div[@class="entry_summary"]/a/img/@src').extract_first("") # 用xpath选取元素并提取出字符串类型的url if image_url.startswith("//"): image_url="https:"+image_url post_url = post_node.xpath('.//h2[@class="news_entry"]/a/@href').extract_first("") # 留神要加点号,示意选取一个区域外部的另一个区域 yield Request(url=parse.urljoin(response.url, post_url), meta={"front_image_url": image_url}, callback=self.parse_detail) # 提取下一页的URL并交给scrapy进行下载 next_url = response.xpath('//a[contains(text(),"Next >")]/@href').extract_first("") yield Request(url=parse.urljoin(response.url, next_url), callback=self.parse) def parse_detail(self, response): match_re = re.match(".*?(\d+)", response.url) if match_re: post_id = match_re.group(1) # title = response.xpath('//div[@id="news_title"]/a/text()').extract_first("") # create_date = response.xpath('//*[@id="news_info"]//*[@class="time"]/text()').extract_first("") # match_re = re.match(".*?(\d+.*)", create_date) # if match_re: # create_date = match_re.group(1) # content = response.xpath('//div[@id="news_content"]').extract()[0] # tag_list = response.xpath('//div[@class="news_tags"]/a/text()').extract() # tags = ",".join(tag_list) # article_item = CnblogsArticleItem() # article_item["title"] = title # article_item["create_date"] = create_date # article_item["content"] = content # article_item["tags"] = tags # article_item["url"] = response.url # if response.meta.get("front_image_url", ""): # article_item["front_image_url"] = [response.meta.get("front_image_url", "")] # else: # article_item["front_image_url"] = [] item_loader=ArticleItemLoader(item=CnblogsArticleItem(),response=response) # item_loader.add_xpath('title','//div[@id="news_title"]/a/text()') # item_loader.add_xpath('create_date', '//*[@id="news_info"]//*[@class="time"]/text()') # item_loader.add_xpath('content', '//div[@id="news_content"]') # item_loader.add_xpath('tags', '//div[@class="news_tags"]/a/text()') item_loader.add_xpath("title", "//div[@id='news_title']/a/text()") item_loader.add_xpath("create_date", "//*[@id='news_info']//*[@class='time']/text()") item_loader.add_xpath("content", "//div[@id='news_content']") item_loader.add_xpath("tags", "//div[@class='news_tags']/a/text()") item_loader.add_value("url",response.url) if response.meta.get("front_image_url", ""): item_loader.add_value("front_image_url",response.meta.get("front_image_url", "")) # article_item=item_loader.load_item() yield Request(url=parse.urljoin(response.url, "/NewsAjax/GetAjaxNewsInfo?contentId={}".format(post_id)), meta={"article_item": item_loader,"url":response.url}, callback=self.parse_nums) def parse_nums(self, response): j_data = json.loads(response.text) item_loader = response.meta.get("article_item", "") # praise_nums = j_data["DiggCount"] # fav_nums = j_data["TotalView"] # comment_nums = j_data["CommentCount"] item_loader.add_value("praise_nums",j_data["DiggCount"]) item_loader.add_value("fav_nums", j_data["TotalView"]) item_loader.add_value("comment_nums", j_data["CommentCount"]) item_loader.add_value("url_object_id", common.get_md5(response.meta.get("url",""))) # article_item["praise_nums"] = praise_nums # article_item["fav_nums"] = fav_nums # article_item["comment_nums"] = comment_nums # article_item["url_object_id"] = common.get_md5(article_item["url"]) article_item = item_loader.load_item() yield article_item这里所说的动静网页技术的处理过程如下:按F12调出开发者模式,刷新后找network,找有Ajax字样的name,点击后查看对应的网址并转入对应的网址就可看出,外面有json格局的数据。外围要害代码如下: ...

March 3, 2022 · 5 min · jiezi

关于python3.x:解决Python命令行报ModuleNotFoundError错误

有一种状况就是在IDE中间接运行没有问题,在命令行中运行异样,本篇次要解决这个问题:1、首先看以后sys外面到底引入的path有多少,在所援用的文件中最下面: import sys print(sys.path) 2、通过命令行去比照,在援用所有模块前去写: 用IDE去执行,看到底path中哪一条没有被引入 3、通过sys.path.append()引入对应的门路即可

January 27, 2022 · 1 min · jiezi

关于python3.x:Python提示包引用错误

在Python的对应site-packages下减少.pth文件: 可能site-packages找不到理论援用的,则间接在对应的ide上来找这个目录,增加这个文件即可: 减少环境对应的目录:

January 27, 2022 · 1 min · jiezi

关于python3.x:python从excel里面获取数据写入word

需要从excel外面写入word数据,如图所示:在word外面构造与所列表格统一:实现,首先各自连贯到对应的表格: 通过循环遍历确保所传入数据的正确性,用if判断表头,保障表头只存储一次,其余数据失常按循环进入存储: 最终实现写入:

January 27, 2022 · 1 min · jiezi

关于python3.x:四位一体水溶交融Docker一拖三Tornado62-Nginx-Supervisord非阻塞负载均衡容器式部署实践

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_203 容器,又见容器。Docker容器的最次要长处就在于它们是可移植的。一套服务,其所有的依赖关系能够捆绑到一个独立于Linux内核、平台散布或部署模型的主机版本的单个容器中。此容器能够传输到另一台运行Docker的主机上,并且在没有兼容性问题的状况下执行。而传统的微服务架构会将各个服务独自封装为容器,尽管微服务容器化环境可能在给定数量的基础架构内实现更高的工作负载密度,然而,在整个生产环境中创立、监督和销毁的容器需要总量呈指数级增长,从而显著减少了基于容器治理环境的复杂性。 藉此,本次咱们将服务化零为整,将Tornado服务和Nginx服务器以及配套的监控管理程序Supervisor集成到一个独自的容器中,将其高度可移植性最大化地施展。 Docker具体装置流程请移玉步到:一寸宕机一寸血,十万容器十万兵|Win10/Mac零碎下基于Kubernetes(k8s)搭建Gunicorn+Flask高可用Web集群 整体容器内的零碎架构如图所示: 首先,创立我的项目目录 mytornado: mkdir mytornado这里web服务框架咱们应用业内驰名的非阻塞异步框架Tornado6.2,创立一个服务的入口文件main.py import json import tornado.ioloop import tornado.web import tornado.httpserver from tornado.options import define, options define('port', default=8000, help='default port', type=int) class IndexHandler(tornado.web.RequestHandler): def get(self): self.write("Hello, Tornado") def make_app(): return tornado.web.Application([ (r"/", IndexHandler), ]) if __name__ == "__main__": tornado.options.parse_command_line() app = make_app() http_server = tornado.httpserver.HTTPServer(app) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start()这里运行端口咱们通过命令行传参的形式进行监听,不便多过程服务的启动。 之后,创立 requirements.txt 我的项目依赖文件: tornado==6.2接下来,创立Nginx的配置文件 tornado.conf upstream mytornado { server 127.0.0.1:8000; server 127.0.0.1:8001; } server { listen 80; location / { proxy_pass http://mytornado; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }这里Nginx监听80端口,反向代理到本地零碎的8000和8001端口,这里咱们应用默认的负载平衡计划:轮询,如果有其余需要,能够依照其余的计划进行批改: ...

January 7, 2022 · 4 min · jiezi

关于python3.x:Python3字符编码-str与bytes类型转化

Python3 最重要的新个性之一是对字符串和二进制数据流做了明确的辨别。文本是Unicode,由str类型示意,二进制数据则由bytes类型示意。Python3 不会以任意隐式的形式混用str和bytes,不能拼接字符串和字节流,也无奈在字节流里搜寻字符串,也不能将字符串传入参数为字节流的函数。 编码是什么?编码就是把一个字符用一个二进制来示意。咱们都晓得,所有的货色,不论是英文、中文还是符号等等,最终存储在磁盘上都是01010101这类货色。 以ASCII编码为例,它规定1个字节8个比特位代表1个字符的编码,也就是“00000000”这么宽,一个一个字节的解读,计算机失去遍及,中文、日文、韩文等等国家的文字须要在计算机内示意,ASCII的255位远远不够,于是规范组织制订出了叫做UNICODE的万国码,它规定任何一个字符(不论哪国的)至多以2个字节示意,于是UTF-8编码应运而生,它规定英文字母系列用1个字节示意,汉字用3个字节示意等等。因而,它兼容ASCII,能够解码晚期的文档。UTF-8很快就失去了宽泛的利用。 bytes和str之间的异同:bytes是一种比特流,它的存在模式是01010001110这种。咱们无论是在写代码,还是阅读文章的过程中,必定不会有人间接浏览这种比特流,它必须有一个编码方式,使得它变成有意义的比特流,而不是一堆艰涩难懂的01组合; >>> s = "中文">>> s'中文'>>> type(s)<class 'str'>>>> b = bytes(s, encoding='utf-8')>>> bb'\xe4\xb8\xad\xe6\x96\x87' #\x 代表是十六进制>>> type(b)<class 'bytes'>Python有个内置函数bytes()能够将字符串str类型转换成bytes类型,结尾的b示意这是一个bytes类型,在应用内置函数bytes()的时候,必须明确encoding的参数(意思是按什么编码方式编成存储的二进制),不可省略。 在python3中提供了encode()和decode()两个函数编码能够将形象字符以二进制数据的模式示意,有很多编码方法,如utf-8、gbk等,能够应用encode()函数对字符串进行编码,转换成二进制字节数据,也可用decode()函数将字节解码成字符串,用decode()函数解码; '''中文编码'''>>> a='中文'>>> type(a)str>>> b=a.encode(encoding='utf-8')>>> bb'\xe4\xb8\xad\xe6\x96\x87' '''中文解码'''>>> c=b.decode(encoding='utf-8')>>> c'中文' '''能够省略解码格局'''>>> d=b.decode()>>> d'中文' '''英文编码'''>>> a='hello'>>> b=a.encode(encoding='utf-8')>>> bb'hello' '''英文解码>>> c=b.decode('utf-8')>>> c'hello'

January 5, 2022 · 1 min · jiezi

关于python3.x:python分析全国各城市景点并可视化显示

此次爬取波及到的库:request+json--网页数据爬取openpyxl--保留数据至Excelpandas--表格数据处理pyechars--数据可视化 一、剖析网页关上去哪儿旅行网页:https://piao.qunar.com/ 二、爬取每个行政区数据取出url和headers须要用到def get_city_scenic(city, page): ua = UserAgent(verify_ssl=False) # headers = {'User-Agent': ua.random} headers = {'user-agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'} # url = f'https://piao.qunar.com/ticket/list.json?keyword={city}&region=&from=mpl_search_suggest&sort=pp&page={page}' url = f'https://piao.qunar.com/ticket/list.json?keyword={city}&region=&from=mpl_search_suggest&page={page}' result = requests.get(url, headers=headers, timeout=10) result.raise_for_status() return get_scenic_info(city, result.text)三、爬取每一页数据def get_scenic_info(city, response): response_info = json.loads(response) sight_list = response_info['data']['sightList'] one_city_scenic = [] for sight in sight_list: scenic = [] name = sight['sightName'] # 景点名称 star = sight.get('star', None) # 星级 score = sight.get('score', 0) # 评分 price = sight.get('qunarPrice', 0) # 价格 sale = sight.get('saleCount', 0) # 销量 districts = sight.get('districts', None) # 省,市,区 point = sight.get('point', None) # 坐标 intro = sight.get('intro', None) # 简介 free = sight.get('free', True) # 是否收费 address = sight.get('address', None) # 具体地址 scenic.append(city) scenic.append(name) scenic.append(star) scenic.append(score) scenic.append(price) scenic.append(sale) scenic.append(districts) scenic.append(point) scenic.append(intro) scenic.append(free) scenic.append(address) one_city_scenic.append(scenic) return one_city_scenic四、循环爬取每个行政区每页数据def get_city_info(city, pages): # for city in cities: one_city_info = [] for page in range(1, pages+1): try: print(f'正在爬取-{city}(省/市), 第{page}页景点数据...') time.sleep(random.uniform(0.8,1.5)) one_page_info = get_city_scenic(city, page) except: continue if one_page_info: one_city_info += one_page_info # print(one_city_info) return one_city_info五、输入到excel表中保留def insert2excel(filepath,allinfo): try: if not os.path.exists(filepath): tableTitle = ['城市','名称','星级','评分','价格','销量','省/市/区','坐标','简介','是否收费','具体地址'] wb = Workbook() ws = wb.active ws.title = 'sheet1' ws.append(tableTitle) wb.save(filepath) time.sleep(3) wb = load_workbook(filepath) ws = wb.active ws.title = 'sheet1' for info in allinfo: ws.append(info) wb.save(filepath) return True except: return False爬取的过程展现: ...

December 16, 2021 · 2 min · jiezi

关于python3.x:Python37-比较两个Excel文件指定列的值的异同并将核对结果写入Excel中

前情形容两份Excel的构造不尽相同,然而有局部字段值能够作为主键,这些列在指标文件中都能找到次要思路:将两个文件的主键作为键,将要核查的列作为值,保留到字典中而后再进行比拟将两个文件将要比拟的字段做成一个列表进行比拟。办法1 代码演示import xlrdimport xlwtimport timelist2 = 'D:\\MyDocuments\\lit\\Desktop\\ares-host-list\\host3.xls'list1 = 'D:\\MyDocuments\\lit\\Desktop\\ares-host-list\\yly3.xls'origin_dict = {} # 初始化,用于保留源文件{key(主键):value(须要核查的列值)}target_dict = {} # 初始化,用于保留指标文件{key(主键):value(须要核查的列值)}def compare_excel(ori_path,tar_path,col_ori,col_tar,keys_ori,keys_tar): ''' ori_path:用于寄存源文件 tar_path:用于寄存指标文件 col_ori:源文件中须要比拟的列 col_tar:指标文件中须要比拟的列 keys_ori:源文件中须要比拟的列的key keys_tar:指标文件中须要比拟的列key 例子:源文件如下:{'p0-app01': '10.130.51.176',} 指标文件如下:{'p0-web03': '10.130.101.26'} else: col_ori = keys_ori ,col_tar = keys_tar 源文件如下:{'10.130.101.152': '10.130.101.152'} 指标文件如下:{'10.81.26.164': '10.81.26.164'} 同样能够比拟(却决于你的两张婊子数据) ''' success = 0 # 核查无差别的个数 fail = 0 # 核查后果有差别的个数 row_res = 0 #要写入的文件的行 # 别离关上源文件与指标文件 wb_ori = xlrd.open_workbook(ori_path) wb_tar = xlrd.open_workbook(tar_path) # 新建一个excel,用于寄存核查后果 wb_res = xlwt.Workbook() # 别离获取源文件与指标文件的sheet sheet_ori = wb_ori.sheet_by_index(0) sheet_tar = wb_tar.sheet_by_index(0) # 新建一名称为result的sheet页,用于寄存核查具体后果 sheet_res = wb_res.add_sheet('D:\\MyDocuments\\lit\\Desktop\\ares-host-list\\result.xlsx') # 获取源文件中由主键、需核查列组成的键值对,放入字典中 for row_ori in range(1,sheet_ori.nrows): cell_ori_key = sheet_ori.cell_value(row_ori,keys_ori) #因我的源文件的主键位于第0列,故该列未参数化,大家能够视本人理论状况进行优化 #cell_ori_key1 = sheet_ori.cell_value(row_ori, 5) cell_ori_value = sheet_ori.cell_value(row_ori,col_ori) origin_dict[cell_ori_key] = cell_ori_value #origin_dict[cell_ori_key + cell_ori_key1] = cell_ori_value print('源文件如下:%s' % origin_dict) # 获取指标文件中由主键、待核查列组成的键值对,放入字典中 for row_tar in range(1,sheet_tar.nrows): cell_tar_key = sheet_tar.cell_value(row_tar,keys_tar) cell_tar_value = sheet_tar.cell_value(row_tar,col_tar) target_dict[cell_tar_key] = cell_tar_value print('指标文件如下:%s' % target_dict) try: for i in origin_dict.keys(): # 获取源文件字典的键 if target_dict.get(i) == origin_dict.get(i): # 比照两个字典中雷同键的值 success += 1 # 值相等,则无差别数+1 sheet_res.write(row_res+1,0,i) # 将键写入后果文件的第0列 sheet_res.write(row_res+1,1,'你俩长一样') #将核查无差别后果写入后果文件的第1列 row_res += 1 # 后果文件行数+1 print('IP %s 核查无差别'% i) else: fail +=1 # 值不相等,则有差别数+1 sheet_res.write(row_res+1,0,i) sheet_res.write(row_res+1,1,'核查有差别:源文件的值为:%s,指标文件的值为:%s' % (origin_dict.get(i),target_dict.get(i))) # #将核查有差别后果写入后果文件的第1列 row_res += 1 # 后果文件行数+1 print('Host IP %s 核查有差别:源文件的值为:%s,指标文件的值为:%s' % (i,origin_dict.get(i),target_dict.get(i))) wb_res.save('D:\\MyDocuments\\lit\\Desktop\\ares-host-list\\result.xlsx') # 保留后果文件 print(time.strftime('%Y-%m-%d %H-%M-%S',time.localtime())+'核查实现,共核查 %d 条,其中无差别 %d 条, 有差别 %d条' % (len(origin_dict),success,fail)) except Exception as error: print(str(error))compare_excel(list1,list2,4,6,4,6) # 核查源文件第5列,指标文件第7列 ...

October 8, 2021 · 1 min · jiezi

关于python3.x:推荐系统基础相似度计算

一.类似度计算方法欧式间隔杰卡德(Jaccard)类似度余弦类似度皮尔逊(Pearson)类似度1.欧式间隔欧式空间下度量间隔的办法,两个物体, 都在同一个空间下示意为两个点, 如果叫做p,q, 别离都是n个坐标, 那么欧式间隔就是掂量这两个点之间的间隔. 欧氏间隔不适用于布尔向量之间计算公式: $$ xE(p,q) = \sqrt{\sum_{i=1}^n (p_i - q_i)^2}$$ 欧氏间隔的值是一个非正数, 最大值正无穷, 通常计算类似度的后果心愿是[-1,1]或[0,1]之间,个别能够应用 如下转化公式: $$ 1/1+E(p,q)$$ 2.杰卡德(Jaccard)两个汇合的交加元素个数在并集中所占的比例, 十分实用于布尔向量示意,分子是两个布尔向量做点积计算, 失去的就是交加元素的个数,母是两个布尔向量做或运算计算公式: 代码实现: def jaccard_similar(): Nu = {'A', 'C', 'D'} Nv = {'A', 'B', 'D', 'E'} similarity = len(Nu & Nv) / len(Nu | Nv) print(similarity)3.余弦类似度度量的是两个向量之间的夹角, 用夹角的余弦值来度量类似的状况,余弦类似度在度量文本类似度, 用户类似度,物品类似度的时候较为罕用余弦类似度的特点, 与向量长度无关,余弦类似度计算要对向量长度归一化, 两个向量只有方向统一,无论水平强弱, 都能够视为'类似'计算公式: 代码实现: def UserSimilarity(train): W = dict() for u in train.keys(): for v in train.keys(): if u == v: continue W[u][v] = len(train[u] & train[v]) W[u][v] /= math.sqrt(len(train[u]) * len(train[v]) * 1.0) return W 4.皮尔逊(Pearson)类似度实际上也是一种余弦类似度, 不过先对向量做了中心化, 向量a b 各自减去向量的均值后, 再计算余弦类似度,皮尔逊相关系数度量的是两个变量的变化趋势是否统一, 不适宜计算布尔值向量之间的相关度计算公式: ...

September 28, 2021 · 1 min · jiezi

关于python3.x:推荐系统基于用户的协同过滤算法实现

一.实现步骤创立数据集计算用户类似度获取类似用户获取类似用户相干物品过滤物品二.代码实现1.筹备数据import pandas as pdusers = ['User1', 'User2', 'User3', 'User14', 'User5', ]items = ['ItemA', 'ItemB', 'ItemC', 'ItemD', 'ItemE']datasets = [ [1, 0, 1, 1, 0], [1, 0, 0, 1, 1], [1, 0, 1, 0, 0], [0, 1, 0, 1, 1], [1, 1, 1, 0, 1],]df = pd.DataFrame(datasets, columns=items, index=users)2.计算用户类似度应用sklearn 的 pairwise_distances 计算用户类似度 # sklearn 不能间接计算类似度,只能计算间隔,应用1- 间隔 就失去类似度user_similar = 1 - pairwise_distances(df.values, metric='jaccard')user_similar = pd.DataFrame(user_similar, columns=users, index=users)3.获取类似的用户topN_users = {}for i in user_similar.index: # 获取每个用户对应行,去除本人对本人的类似度 _df = user_similar.loc[i].drop([i]) # 对获取行进行排序 _df_sorted = _df.sort_values(ascending=False) # 获取类似度最高类似度的两个用户 top2 = list(_df_sorted.index[:2]) # 将获取到的类似用户放入汇合 topN_users[i] = top24. 获取类似用户相干物品并过滤物品rs_results = {}# 对类似用户汇合循环for user, sim_users in topN_users.items(): res_result = set() # 获取每个用户的汇合 for sim_user in sim_users: # 获取每个类似用户对应的物品的index res_result = res_result.union(set(df.loc[sim_user].replace(0, np.nan).dropna().index)) # 过滤掉举荐用户曾经看过的物品 res_result -= set(df.loc[user].replace(0, np.nan).dropna().index) rs_results[user] = res_result 后果{'User1': {'ItemE'}, 'User2': {'ItemC', 'ItemB'}, 'User3': {'ItemE', 'ItemB', 'ItemD'}, 'User14': {'ItemA', 'ItemC'}, 'User5': {'ItemD'}}残缺代码import pandas as pdfrom sklearn.metrics import jaccard_scorefrom sklearn.metrics.pairwise import pairwise_distancesimport numpy as npusers = ['User1', 'User2', 'User3', 'User14', 'User5', ]items = ['ItemA', 'ItemB', 'ItemC', 'ItemD', 'ItemE']datasets = [ [1, 0, 1, 1, 0], [1, 0, 0, 1, 1], [1, 0, 1, 0, 0], [0, 1, 0, 1, 1], [1, 1, 1, 0, 1],]df = pd.DataFrame(datasets, columns=items, index=users)# score = jaccard_score(df['ItemA'], df['ItemB'])# print(score)print(df)user_similar = 1 - pairwise_distances(df.values, metric='jaccard')user_similar = pd.DataFrame(user_similar, columns=users, index=users)topN_users = {}for i in user_similar.index: _df = user_similar.loc[i].drop([i]) _df_sorted = _df.sort_values(ascending=False) top2 = list(_df_sorted.index[:2]) topN_users[i] = top2# print(topN_users)rs_results = {}for user, sim_users in topN_users.items(): res_result = set() for sim_user in sim_users: res_result = res_result.union(set(df.loc[sim_user].replace(0, np.nan).dropna().index)) res_result -= set(df.loc[user].replace(0, np.nan).dropna().index) rs_results[user] = res_resultprint(rs_results)

September 27, 2021 · 2 min · jiezi

关于python3.x:深度学习实践使用faceNet-进行人脸识别

1.下载facenet模型facenet须要通过大量的运算,所以间接应用他人训练过的权重链接:https://pan.baidu.com/s/1CGyz... 提取码:pew0 2. 应用的工具1. facenet 预训练模型,用于获取人脸特色2. mtcnn 用于人脸检测并返回对应参数3. 代码实现1. 加载模型from keras.models import load_modelfrom mtcnn import MTCNN# 加载mtcnndector = MTCNN()# 加载facenet模型model = load_model('facenet_keras.h5')2.依据图片检测人脸def extract_face(detector, file_name, required_size=(160, 160)): # detector:mtcnn 对象,file_name:图片门路 # 加载图片 image = Image.open(file_name) # 将图片转换黑白 image = image.convert('RGB') # 将图片转换为 array pixels = asarray(image) # 应用 mtcnn 检测人脸 results = detector.detect_faces(pixels) # 返回人脸地位信息 x1, y1, width, height = results[0]['box'] x1, y1 = abs(x1), abs(y1) x2, y2 = x1 + width, y1 + height # 从图片剪裁人脸 face = pixels[y1:y2, x1:x2] # 将剪裁的人脸矩阵化 image = Image.fromarray(face) # 调整检测人脸图片大小 image = image.resize(required_size) # 调整矩阵形态 face_array = asarray(image).reshape(1, 160, 160, 3) return face_array3.应用facenet 提取人脸特色def pre_process(x): if x.ndim == 4: axis = (1, 2, 3) size = x[0].size elif x.ndim == 3: axis = (0, 1, 2) size = x.size else: raise ValueError('Dimension should be 3 or 4') mean = np.mean(x, axis=axis, keepdims=True) std = np.std(x, axis=axis, keepdims=True) std_adj = np.maximum(std, 1.0 / np.sqrt(size)) y = (x - mean) / std_adj return ydef get_embedding(model, img): face_img = pre_process(img) pre = model.predict(face_img) pre = l2_normalize(np.concatenate(pre)) pre = np.reshape(pre, [128]) return pre4.人脸特色比照当从输出的两张图片中获取到人脸特色后,须要将两张图片的特色进行比照,具体能够参考吴恩达老师的深度学习视频 ...

September 22, 2021 · 3 min · jiezi

关于python3.x:深度学习实践使用CelebASpoof训练的权重测试NUAA

1.间接应用保留的网络测试NUAA测试代码: def read_test_file(): base_path = r'E:\ml\fas\data\NUAA' val_file_path = os.path.join(base_path, "test.txt") train_image_path_list = [] train_labels_list = [] with open(val_file_path) as f: lines = f.readlines() for line in lines: image_path = line.split(',')[0] label = line.split(',')[1] img = cv2.imread(image_path) resize_img = cv2.resize(img, (100, 100)) train_image_path_list.append(resize_img) train_labels_list.append(int(label)) return np.asarray(train_image_path_list), np.asarray(train_labels_list)def fit2(): X_test, y_test = read_test_file() model = load_model('model/live_model.h5') test_loss, test_acc = model.evaluate(X_test, y_test, verbose=2) print(test_loss, test_acc)if __name__ == '__main__': fit2()测试后果 200/200 - 8s - loss: 1.3156 - accuracy: 0.52851.3155993223190308 0.5284998416900635能够看到CelebA_Spoof 在本人的数据集测试能够达到99%以上然而在NUAA数据集上测试准确率只能达到: 0.528查看CelebA_Spoof 数据集后发现,CelebA_Spoof 的spoof数据集都是图像打印在纸上的加头像,然而NUAA外面是电脑屏幕或者手机屏幕录取的图片 ...

September 20, 2021 · 2 min · jiezi

关于python3.x:Python入门基础小套路

Python是世界上最最最风行的编程语言之一Python曾经间断多年占据各种语言的排行榜第一位,在数据分析畛域和R语言,之前始终是不分伯仲,但在最近几年,Python受欢迎水平越来越高,越来越多的Python剖析工具库像雨后春笋般冒了进去,很多开源的数据分析库受到数据分析师们的欢送。从数据采集、荡涤、解决、剖析、报表、数据挖掘、机器学习,Python都提供了成熟的解决方案,能够说学会了Python,能够在数据分析畛域上天入地。事实上,Python的一些罕用库,比方像数据分析三剑客(Numpy/Pandas/Matpolib)等等,曾经成为各大互联网企业的数据分析师们日常必备工具。Python在各个领域都有着广泛应用,包含数据分析、服务器开发、运维开发、人工智能开发,甚至少儿编程也开始引入Python。可用版本目前有两个:1. Python 22. Python 3这两个版本只存在一些细微差别,前者面上技术市场较早,遍及度较高,社区比拟沉闷,但Python官网已于2020年1月1日起不再保护,因而当初主推Python 3,取而代之只是工夫的问题,好在区别不大,还是举荐开发者用Python 3吧。从开发环境来说次要有两种:1. 命令行交互模式: 2. 集成开发环境(PyCharm): 两种形式各有优缺点,简略说来就是,交互模式简洁,功能强大,然而难操作,要想吃鸡全靠记,多行编码简单;IDE环境,命令直观,易上手,需额定软件或插件反对,哪里不会点哪里。编码方式没有好坏之分,择其“擅”者而从之,兴许命令行模式下的几个字符能实现的性能,在IDE里要点半天,兴许IDE里的快捷命令菜单点一下就能预写出大段难记的命令。比方Vim、Lua、Scala,亦或spark-shell、hbase shell、zkCli.sh,再比方Eclipse、IEDA、Visual Studio、VS Code、XCode,交互模式就是技术的里子,IDE就是技术的体面,里外都拿下,那就成大佬了。总之交互模式下,就是与技术外围的零距离接触,IDE模式下,就是隔山打牛,利器加身,老手先用IDE,经验丰富了再钻研交互模式,定会发现奥妙无穷。接入正题变量申明篇x, y = 123,456print(x, y)123 456 #快捷替换x, y = y, xprint(x, y)456 123 输入篇print("Hello World")Hello World print("Hello" , "World")Hello World print("Hello" + "World")HelloWorld print("My age is", 18)My age is 18 #ERRORprint("My age is " + 18)Traceback (most recent call last): File "F:/lagou/TestPython/helloworld.py", line 1, in <module> print("My age is " + 18)TypeError: must be str, not intprint("My age is " + str(18)) ...

August 27, 2021 · 2 min · jiezi

关于python3.x:如何编写一个-Python-Web-应用-零

最近在为一个开源社区开发一个 FAQ (Frequently Asked Questions) 服务模块, 开发语言我抉择了 Python. 这也是我第一次应用 Python 编写 Web服务. 之前我始终习惯用 Java 来进行 Web 后端开发, 而我相熟的一套最根底的 Java Web 技术栈是这样的: Spring X: 整个利用的框架, 这里的 'X' 包含 'boot', 'cloud', 等等Mybatis/Mybatis-plus: 数据库 ORMMybatis-plus-generator: 逆向工程, 即由数据库生成 DAO. 但它能做的不止于此, 它还能够生成整个目录构造fastjson/gson/jackson: json 解析Maven/gradle: 依赖治理. 应用一个 pom.xml/build.gradle 文件使得我的项目能够疾速构建环境而与之对应的, Python 中的一套最根本的技术栈: Flask: 整个利用的框架Flask-SQLAlchemy: SQLAlchemy 在 flask 中的插件. 用于数据库 ORM. 相比 Java, 它提供了更灵便的接口, 尤其是对于简单关系flask-sqlacodegen: 针对 SQLAlchemy 的逆向工程jsonschema: 用于 json 申请体的校验pip: 依赖治理. 对于 Web 开发来说, pip 曾经足够了当然还有其余抉择,毕竟工程问题,没有真谛。比方同样很火的框架 Django 也很值得一试,但我集体更习惯 flask 的轻量灵活性 ...

August 19, 2021 · 1 min · jiezi

关于python3.x:用这一行代码实现简化Python异常信息不再令人头大你不妨试试

即便是 Python,报错时也令人头大。你是不是常常碰到呢? 那么,明天它来了~ Python 异样输入丑化工具PrettyErrors理解一下?(后续都用它或者TA示意) 只需一个 import,报错也能整齐划一,错误代码地位、谬误起因清晰明了,一眼就能看清。 一行代码简化报错 先来试试一个简略的谬误 def foo(): 1/0foo()在不应用它之前,报错信息长这样: 让咱们来 import 一下 pretty_errors。输入会变成什么样子呢: 是不是清晰简洁了很多呢?当然它还能够自定义色彩。 报错的信息少的时候,还不感觉有什么问题。 当报错信息铺满一整页,好看不美观,对心里承受能力水平就有所不同了。 user's guidance像 Python 的所有第三方库一样,TA的装置非常简略。 python -m pip install pretty_errors如果你想让你的每一个程序都能这样在报错时也放弃美貌,那么运行上面这这行命令,就不必每次都导入TA。 python -m pretty_errors并且,如此一来,语法错误(SyntaxError)的格局也同样能被丑化。仅在程序中 import pretty_errors 时,这一点是无奈实现的。 想要打造本人称心的丑化成果,那就试试这几个函数: pretty_errors.configure()pretty_errors.whitelist()pretty_errors.blacklist()pretty_errors.pathed_config()比方要扭转输入文件名的色彩,代码是这样的: pretty_errors.configure(filename_color = pretty_errors.BRIGHT_YELLOW)如果你发现下面操作之后,啥也没扭转,那就检查一下 PYTHON_PRETTY_ERRORS,当它的值为 0 时,PrettyErrors 是被禁用的。 set PYTHON_PRETTY_ERRORS=1须要留神的是,你应用的终端自身具备色彩输入性能,异样信息输入才会带有不同的色彩。 如果不巧你习用的是单色终端,那么能够试试 pretty_errors.mono() 中的设置。人生苦短,bug 实多,何不试试 TA,给 Debug 的过程增加几分美感。 文章到这里就完结了,感激你的观看,Python小技巧系列,下个系列分享Python给程序增加进度条 为了感激读者们,我想把我最近珍藏的一些编程干货分享给大家,回馈每一个读者,心愿能帮到你们。 干货次要有: ① 2000多本Python电子书(支流和经典的书籍应该都有了) ② Python规范库材料(最全中文版) ③ 我的项目源码(四五十个乏味且经典的练手我的项目及源码) ④ Python根底入门、爬虫、web开发、大数据分析方面的视频(适宜小白学习) ⑤ Python学习路线图(辞别不入流的学习) ...

August 19, 2021 · 1 min · jiezi

关于python3.x:Python第三方库下载速度慢用这一招让你pip下载速度起飞

明天给大家分享的是如何使pip下载速度能够“飞”起来。 国内的镜像源次要有: 阿里云:http://mirrors.aliyun.com/pyp...中国科技大学:https://pypi.mirrors.ustc.edu...豆瓣:http://pypi.douban.com/simple清华大学:https://pypi.tuna.tsinghua.ed...在这里举荐应用清华大学的下载源,下载速度快,且稳固。 1、我用progressbar测试,应用“阿里云”镜像源无奈下载;应用“清华”的镜像源完满下载。 ![图片<没有找到>](https://img-blog.csdnimg.cn/f...<没有找到> <胜利装置> 2、用jieba测试,应用镜像下载的速度的确感觉“腾飞了”一样。 那该如何应用呢? 只须要在 pip 装置的时候,加上相应的镜像源就能够了。 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple jieba为了方便使用,我整顿了一个小脚本,可供用户抉择“镜像源”和须要下载的“扩大库”名称。 运行脚本,即可下载该扩大库。 import osmirrors = {"清华":"https://pypi.tuna.tsinghua.edu.cn/simple ", "阿里云":"http://mirrors.aliyun.com/pypi/simple ", "中科大":"https://pypi.mirrors.ustc.edu.cn/simple ", "豆瓣":"http://pypi.douban.com/simple " }print("清华 | 阿里云 | 中科大 | 豆瓣")web = input("请输入您想抉择的镜像源名称(举荐应用清华):")lib = input("请输入您想装置的扩大库名称:")# 抉择其中一个镜像源,下载安装库os.system("pip3 install -i "+ mirrors[web] + lib)运行成果如图 如果还感觉麻烦,能够进行如下配置,让pip装置的时候默认应用配置好的镜像源下载库。 间接在user目录中创立一个pip目录:C:\Users\xxx\pip(Windows用户)新建文件“pip.txt”输出以下内容: [global]index-url = https://pypi.tuna.tsinghua.edu.cn/simple4、重命名文本文件为“pip.ini” 就这样,当前再应用pip下载的时候就默认应用镜像源了。 文章到这里就完结了,感激你的观看,Python小技巧系列,下个系列分享简化Python异样信息 为了感激读者们,我想把我最近珍藏的一些编程干货分享给大家,回馈每一个读者,心愿能帮到你们。 干货次要有: ① 2000多本Python电子书(支流和经典的书籍应该都有了) ② Python规范库材料(最全中文版) ③ 我的项目源码(四五十个乏味且经典的练手我的项目及源码) ④ Python根底入门、爬虫、web开发、大数据分析方面的视频(适宜小白学习) ⑤ Python学习路线图(辞别不入流的学习) ...

August 18, 2021 · 1 min · jiezi

关于python3.x:用Python图像识别技术打造一个小狗分类器实现让机器自己去学习

前言今日给大家带来的是图像识别技术——小狗分类器 工具应用开发环境:win10、python3.6开发工具:pycharm工具包 :keras,numpy, PIL 成果展现训练集的准确率为0.925,但测试集只有0.7阐明过拟合了,能够再减少一些图片,或者应用数据加强,来缩小过拟合。 测试了两张图片,全都辨认对了! 思路剖析1 筹备数据集2 数据集的预处理3 搭建卷积神经网络4 训练5 预测1、筹备数据集咱们能够通过爬虫技术,把4类图像(京巴、拉布拉多、柯基、泰迪)保留到本地。总共有840张图片做训练集,188张图片做测试集。 2 数据集的预处理1 对立尺寸为1001003(RGB彩色图像)# 对立尺寸的外围代码img = Image.open(img_path)new_img = img.resize((100, 100), Image.BILINEAR)new_img.save(os.path.join('./dog_kinds_after/' + dog_name, jpgfile))2 因为数据是本人下载的,须要制作标签(label),可提取图像名称的第一个数字作为类别。(重命名图片)kind = 0# 遍历京巴的文件夹images = os.listdir(images_path)for name in images: image_path = images_path + '/' os.rename(image_path + name, image_path + str(kind) +'_' + name.split('.')[0]+'.jpg')3 划分数据集840张图片做训练集,188张图片做测试集。 4 把图片转换为网络须要的类型# 只放了训练集的代码,测试集一样操作。ima_train = os.listdir('./train')# 图片其实就是一个矩阵(每一个像素都是0-255之间的数)(100*100*3)# 1.把图片转换为矩阵def read_train_image(filename): img = Image.open('./train/' + filename).convert('RGB') return np.array(img)x_train = []# 2.把所有的图片矩阵放在一个列表里 (840, 100, 100, 3)for i in ima_train: x_train.append(read_train_image(i))x_train = np.array(x_train)# 3.提取kind类别作为标签y_train = []for filename in ima_train: y_train.append(int(filename.split('_')[0]))# 标签(0/1/2/3)(840,)y_train = np.array(y_train)# 我是因为重命名图片为(1/2/3/4),所以都减了1# 为了可能转化为独热矩阵y_train = y_train - 1 # 4.把标签转换为独热矩阵# 将类别信息转换为独热码的模式(独热码有利于神经网络的训练)y_train = np_utils.to_categorical(y_train)y_test = np_utils.to_categorical(y_test)print(y_test)x_train = x_train.astype('float32')x_test = x_test.astype('float32')x_train /= 255x_test /= 255print(x_train.shape) # (840, 100, 100, 3)print(y_train.shape) # (840,)3 搭建卷积神经网络Keras是基于TensorFlow的深度学习库,是由纯Python编写而成的高层神经网络API,也仅反对Python开发。 ...

August 17, 2021 · 1 min · jiezi

关于python3.x:用-Python3-实现瓣变巨肚

概述光彩的游戏《三国志曹操传》置信很多人都玩过。当年因为乱码,导致很多人没有方法玩耍正确的简体中文版,而是玩的全程不知所云的乱码版。其中,曹操就是赫赫有名的“变巨”。“瓣变巨肚”其实就是“三国志曹操传”的乱码版本。 闲话不多说了。明天我想和大家分享一下,怎么用短短几行 Python 代码重现上述的编码谬误。 Python 实现及原理起初,这款游戏被台湾引进,并翻译成了繁体中文版。过后还没有遍及 Unicode,所以各地都有本人的一套编码字符集。台湾应用的是 Big5,而大陆过后应用的广泛是 GB2312、GBK 等。所以,咱们只须要把正确的内容依据 Big5 进行编码,而后再用 GBK 进行解码,就能失去如题目那样的乱码了。 import codecsword = '曹操'byte = codecs.encode(word, 'big5')res = codecs.decode(byte, 'gbk')print(res)这样,咱们就失去了“变巨”。那是不是这样就完结了?其实并没有。比方咱们还能够试试“三國志曹操傳”。留神这里用的是繁体。咱们可不心愿用 Big5 编码简体字,毕竟台湾用的可不是简体中文。 后果竟然报错了: UnicodeDecodeError: 'gbk' codec can't decode byte 0xa4 in position 0: illegal multibyte sequence这是因为,Big5 和 GBK 所涵盖的二进制编码有各自“专属”,也就是不属于二者交加的局部。上述的 0xa4 就是其中之一。遇到这个状况,GBK 无奈辨认,于是就报错了。 那么怎么解决呢?其实也很简略,只须要给 decode() 加一个疏忽报错即可: res = codecs.decode(byte, 'gbk', 'ignore')这个 ignore 的作用就是疏忽解码过程中遇到的无奈辨认的编码。其余可选的还有 strict 等。详见 这样,咱们就能够“正确”地失去后果了: T瓣变巨肚为什么结尾会有一个“T”?其实结尾那个是一个无奈被 GBK 辨认的字节。在比拟旧的操作系统上会显示为“?”,或者罗唆空白。 其实认真看的话,当年的标题栏的确结尾是有一个空白的。咱们换一个老一点的控制台,也是能够看到雷同的成果的:

August 14, 2021 · 1 min · jiezi

关于python3.x:Python造假数据用扩展库Faker足够了附源码

前言明天用Python给大家造“假”数据,间接开整~ 开发工具Python版本:3.6.4相干模块:Faker Faker扩大库这时,Python扩大库Faker来了,带着它那各种各样的数据来了。 先装置faker pip install Faker创立faker对象 from faker import Fakerfake = Faker()随机生成一个名字 fake.name() # 'Nancy Horton'上边生成的名字是英文的,如果想要个中文名字,在创立Faker对象的时候,指定语言“中文”就能够。 fake = Faker("zh_CN")一些罕用的语言包含以下等等: 简体中文:zh_CN繁体中文:zh_TW美国英文:en_US英国英文:en_GB德文:de_DE日文:ja_JP韩文:ko_KR法文:fr_FR都有什么样的数据faker 提供了一些Standard Providers,列出了一些较为较为罕用的数据。 addresscompanydate_timejobpersonphone_numberprofilepythonuser_agent比方生成“地址”信息 In [1]: fake.address()Out[1]: '北京市大冶市海陵赵路x座 941837'这里给出的是一整条“地址”的信息,你也能够通过building_number()、city()、street_address()等获取单个信息 这些字段其实记不住也没什么,须要用哪个的时候查阅官网文档就行。 文档链接 https://faker.readthedocs.io/...再比方生成“职位”信息 In [2]: fake.job()Out[2]: '教育/Python工程师'生成python的数据类型 # 生成一个字典In [3]: fake.pydict()Out[3]:{'生产': 'OlmMWPfQMJYxeiJtZSFC', '有些': 'jUYzbWgDEqvzjiAsubSX', '资源': 7670, '利用': 804210265906561.0, '国内': 9113, '电影': 'https://yangtang.cn/homepage.jsp', '方面': 'RGfbqIgxqTbnjkGDpoVO', '为什': 1947, '地址': 7021, '时候': 'oxia@hotmail.com'}生成user_agent In [4]: fake.chrome()Out[4]: 'Mozilla/5.0 (iPad; CPU iPad OS 4_2_1 like Mac OS X) AppleWebKit/531.2 (KHTML, like Gecko) CriOS/55.0.807.0 Mobile/62B715 Safari/531.2'生成个人信息 ...

August 11, 2021 · 1 min · jiezi

关于python3.x:Python实用案例私人定制Python自动化生成爱豆专属2021日历

前言明天给大家用Python脚本实现自动化生成爱豆日历。 成果展现 开发工具python版本: 3.9.4 相干模块: openpyxl模块 calendar模块 以及一些python自带的模块 常识补充一个Excel电子表格文档称为一个工作薄。一个工作薄保留在扩大名为「.xlsx」的文件中。 划重点,openpyxl只反对「.xlsx」类型的格局。所以对于Excel2003版「.xls」格局是不反对的。 每个工作薄能够蕴含多个表,又称为工作表。本次生成的信息就是在一个工作薄,12个工作表内。 calendar库次要是生成日历信息。 源码import calendar# 设置每周的起始日期码,为星期天calendar.setfirstweekday(firstweekday=6)# 返回2019年年历print(calendar.calendar(2019, w=2, l=1, c=6))输入如下 返回1月份每列信息状况 # 返回每月每列信息print(calendar.monthcalendar(2019, 1))# 输入后果[[0, 0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11, 12], [13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26], [27, 28, 29, 30, 31, 0, 0]]与上图里1月份信息比拟下,你会发现多了个数字0。 其余齐全一样,所以遍历列表信息就完事了。 实现爱豆日历from openpyxl.styles import Alignment, PatternFill, Fontfrom openpyxl.utils import get_column_letterfrom openpyxl.drawing.image import Imageimport openpyxlimport calendar# 设置第一天为星期天calendar.setfirstweekday(firstweekday=6)# 创立一个工作䈬wb = openpyxl.Workbook()# 遍历12个月for i in range(1, 13): # 增加工作表 sheet = wb.create_sheet(index=0, title=str(i) + '月') # 获取具体日期工夫 for j in range(len(calendar.monthcalendar(2019, i))): for k in range(len(calendar.monthcalendar(2019, i)[j])): value = calendar.monthcalendar(2019, i)[j][k] # 将0值变为空值 if value == 0: value = '' sheet.cell(row=j + 9, column=k + 1).value = value else: sheet.cell(row=j + 9, column=k + 1).value = value # 设置字体 sheet.cell(row=j + 9, column=k + 1).font = Font(u'微软雅黑', size=11) # 单元格文字设置,右对齐,垂直居中 align = Alignment(horizontal='right', vertical='center') # 单元格填充色属性设置 fill = PatternFill("solid", fgColor="B9EBF7") # 对单元格进行色彩填充 for k1 in range(1, 100): for k2 in range(1, 100): sheet.cell(row=k1, column=k2).fill = fill # 增加星期几信息行 days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'] num = 0 for k3 in range(1, 8): sheet.cell(row=8, column=k3).value = days[num] sheet.cell(row=8, column=k3).alignment = align sheet.cell(row=8, column=k3).font = Font(u'微软雅黑', size=11) # 设置列宽12 c_char = get_column_letter(k3) sheet.column_dimensions[get_column_letter(k3)].width = 12 num += 1 # 设置行高30 for k4 in range(8, 14): sheet.row_dimensions[k4].height = 30 # 合并单元格 sheet.merge_cells('I1:P20') # 增加图片 img = Image('huge_2.jpg') sheet.add_image(img, 'I1') # 增加年份及月份 sheet.cell(row=3, column=1).value = '2019年' sheet.cell(row=4, column=1).value = str(i) + '月' # 设置年份及月份文本属性 sheet.cell(row=3, column=1).font = Font(u'微软雅黑', size=16, bold=True, color='FF7887') sheet.cell(row=4, column=1).font = Font(u'微软雅黑', size=16, bold=True, color='FF7887') sheet.cell(row=3, column=1).alignment = align sheet.cell(row=4, column=1).alignment = align# 保存文档wb.save('爱豆日历.xlsx')文章到这里就完结了,感激你的观看,Python实用脚本系列,下篇文章分享python打造实时截图辨认OCR ...

August 9, 2021 · 2 min · jiezi

关于python3.x:Python实用案例python10行脚本打造实时截图识别OCR轻松搞定百度文库

前言明天,咱们就来做一款实时截图辨认的小工具 开发工具Python版本: 3.9.4 相干模块: PIL模块 keyboard模块 pytesseract模块 以及一些Python自带的模块 效果图展现 源码剖析期待用户截图此处须要借助贴图神器(Snipaste)其中“f1”是截图的快捷键,“ctrl+c”是把截图保留到剪贴板的快捷键。 如果应用qq截图的话,须要把快捷键改为对应的“ctrl+alt+c”和“enter” import keyboard# 利用截图软件(Snipaste)截图到剪贴板# 输出键盘的触发事件keyboard.wait(hotkey="f1") keyboard.wait(hotkey="ctrl+c")time.sleep(0.1)下面这段代码执行之后,当初曾经有一张图片期待在剪贴板里了。 保留截图利用PIL模块的ImageGrab,能够把剪贴板里的那张图片,保留到以后的目录下,并命名为“screen.png” from PIL import ImageGrab# 把图片从剪切板保留到以后门路image = ImageGrab.grabclipboard() image.save("screen.png")辨认截图中的文本 办法一 pytesseract模块 长处:收费,易用毛病:辨认成果很个别,准确率不高 应用办法介绍: pip install pytesseract装置 tesseract-ocr.exe 配置环境变量批改pytesseract.py文件,将tesseract_cmd指向Tesseract-OCR的tesseract.exe的绝对路径。来看看成果: 办法二 百度API接口 AI开放平台文档核心https://ai.baidu.com/ai-doc 查看python语言的SDK文档点击右上角(控制台),登录本人的百度账号,创立“文字辨认”的利用 import pytesseractfrom aip import AipOcrfrom PIL import ImageGrab# 法二:利用百度APIAPP_ID = '你的 App ID'API_KEY = '你的 Api Key'SECRET_KEY = '你的 Secret Key'client = AipOcr(APP_ID, API_KEY, SECRET_KEY)# 读取图片with open("screen.png", 'rb') as f: image = f.read() # 调用百度API通用文字辨认(高精度版),提取图片中的内容 text = client.basicAccurate(image) result = text["words_result"] for i in result: print(i["words"])文章到这里就完结了,感激你的观看,Python实用脚本系列,下篇文章分享python打造实时截图辨认OCR ...

August 7, 2021 · 1 min · jiezi

关于python3.x:Python实用案例Python脚本实现玩转emoji我微又偷偷更新这个表情

前言明天咱们就利用Python脚本实现天气查问利用吧。间接开整~ 成果展现emoji的编码Emoji 字符是 Unicode 字符集中的一部分。也就是说,Emoji 符号就是一个文字,它会被渲染为图形。 常见的 Emoji 表情在 Unicode 字符集中的范畴和具体的字节映射关系, 可通过 Unicode 映射表查看。 Unicode 只是规定了 Emoji 表情的码点和含意,并没有规定它的款式。同一个 Emoji 表情在不同零碎中会有不一样的表现形式。 在python中玩转 emoji在上图的 Unicode 映射表中,能够查到表情对应的 Unicode 编码。 例如表情 的 Unicode 编码为 U+1f637 ,但咱们在应用的时候,须要改写为如下模式能力打印进去:行将+号改为三个零,并在U后面加上斜杠。 In [20]:sample_ list = ["\U0001F601", "\U0001F605 ”, "\U0001F602" ,”\U0001F642", "\U0001F643","\U0001F609 ""\U0001 F60A" , "\U0001F607" ]for code in sample_ list:print( code , end=''在python中,咱们还能够利用扩大库 emoji ,这个库给表情起了“别名”(见下图),以便通过“别名”,获取emoji表情。 源码实现In[32]:from emoji import emojizeprint( emojize(" :smile:", use_ _aliases=True),end='' )print( emojize(" :cry:",use_ aliases=True), end='' )print( emojize(" :pensive:", use_ aliases=True),end=' ' )print( emojize(" :joy:", use_ aliases=True), end='' )文章到这里就完结了,感激你的观看,Python实用脚本系列,下篇文章分享python打造实时截图辨认OCR ...

August 6, 2021 · 1 min · jiezi

关于python3.x:Python实用案例Python脚本实现快速卡通化人物头像让我想起了QQ秀时光

往期回顾Python脚本实现天气查问利用 Python实现主动监测Github我的项目并关上网页 Python实现文件主动归类 Python实现帮你抉择双色球号码 Python实现每日更换“必应图片”为“桌面壁纸” Python实现批量加水印 Python实现破译zip压缩包 Python实现批量下载百度图片 前言明天咱们就利用Python脚本实现天气查问利用吧。间接开整~ 思路剖析从大量照片/卡通数据中习得照片到卡通画的映射。 开发工具python版本: 3.6 相干模块: pytorch 1.4 tensorflow-gpu 1.14 face-alignment dlib 1.数据筹备训练数据包含实在照片和卡通画像,为升高训练复杂度,该我的项目对两类数据进行了如下预处理: 检测人脸及关键点。依据关键点旋转校对人脸。将关键点边界框按固定的比例扩张并裁剪出人脸区域。应用人像宰割模型将背景置白。我的项目开源了204张解决后的卡通画数据,您还需筹备约1000张人像照片(为匹配卡通数据,尽量应用亚洲年老女性照片,人脸大小最好超过200x200像素),应用以下命令进行预处理: python data_process.py --data_path YourPhotoFolderPath --save_path YourSaveFolderPath将解决后的数据依照以下层级寄存,trainA、testA中寄存照片头像数据,trainB、testB中寄存卡通头像数据。 ├── dataset └── photo2cartoon ├── trainA ├── xxx.jpg ├── yyy.png └── ... ├── trainB ├── zzz.jpg ├── www.png └── ... ├── testA ├── aaa.jpg ├── bbb.png └── ... └── testB ├── ccc.jpg ├── ddd.png └── ...从新训练:python train.py --dataset photo2cartoon加载预训练参数: python train.py --dataset photo2cartoon --pretrained_weights models/photo2cartoon_weights.pt测试将一张测试照片(亚洲年老女性)转换为卡通格调: ...

August 5, 2021 · 1 min · jiezi

关于python3.x:万字总结推荐几个常用数据可视化第三方库附源码建议收藏

前言数据可视化的第三方库挺多的,这里我次要举荐三个,别离是 Pygal、Bokeh、Plotly,废话不多说,间接上~~ 举荐数据可视化的库有挺多的,这里举荐几个比拟罕用的: MatplotlibPygalBokehSeabornGgplotPlotlyPyechartPygalpygal官网地址(http://www.pygal.org/en/stable/) 装置pygal模块pygal模块的装置非常简单,只需输出一行pip命令即可 1 pip install pygal装置实现: pygal模块介绍pygal是Python的第三方库,他的次要性能就是数据可视化,行将数字转化成图表的模式来出现,它提供的图表款式有柱状图、折线图、饼状图、雷达图...... 柱状图单列柱状图import pygalview = pygal.Bar()#图表名view.title = '柱状图'#增加数据view.add('numbers', [0,2,4,6,8,10])#在浏览器中查看#view.render_in_browser()#保留为view.svg(也能够保留为jpg)view.render_to_file('view.svg')效果图:留神:svg图片用零碎自带的图片查看器关上可能会显示全彩色,能够尝试应用Google浏览器关上 多列柱状图#增加数据view.add('numbers', [0,2,4,6,8,10])view.add('numbers_2', [0,1,3,5,7,9]) 重叠柱状图view = pygal.StackedBar() 横向柱状图view = pygal.HorizontalStackedBar() 折线图简略折线图import pygalview = pygal.Line()#图表名view.title = '折线图'#增加数据view.add('numbers', [0,2,4,6,8,10])view.add('numbers_2', [0,1,3,5,7,9])#在浏览器中查看#view.render_in_browser()#保留为view.svg(也能够保留为jpg)view.render_to_file('view.svg')效果图: 纵向折线图view = pygal.HorizontalLine() 重叠折线图view = pygal.StackedLine(fill=True) 饼状图简略饼状图import pygalview = pygal.Pie()#图表名view.title = '饼状图'#增加数据view.add('A', 31)view.add('B', 55)view.add('C', 14)#保留为view.svg(也能够保留为jpg)view.render_to_file('view.svg')效果图: 多级饼状图#增加数据view.add('A', [31,25])view.add('B', [55,38])view.add('C', [14,37]) 圆环图#设置空心圆半径view = pygal.Pie(inner_radius=0.4) 半圆图view = pygal.Pie(half_pie=True) 雷达图根底雷达图 import pygalview = pygal.Radar()#图表名view.title = '雷达图'#增加数据(能够为任意个)view.add('A', [31,56,34,67,34])view.add('B', [23,18,57,45,35])view.add('C', [14,45,76,34,76])#保留为view.svg(也能够保留为jpg)view.render_to_file('view.svg')效果图: ...

August 4, 2021 · 5 min · jiezi

关于python3.x:Python实用案例Python脚本实现天气查询应用提醒她注意保暖

往期回顾Python实现主动监测Github我的项目并关上网页 Python实现文件主动归类 Python实现帮你抉择双色球号码 Python实现每日更换“必应图片”为“桌面壁纸” Python实现批量加水印 Python实现破译zip压缩包 Python实现批量下载百度图片 前言明天咱们就利用Python脚本实现天气查问利用吧。间接开整~ 成果预览: 一、获取天气信息应用python获取天气有两种形式。 1、是通过爬虫的形式获取天气预报网站的HTML页面,而后应用xpath或者bs4解析HTML界面的内容。 2、另一种形式是依据天气预报网站提供的API,间接获取结构化数据,省去了解析HTML页面的步骤。 本例应用的是第二种形式,申请地址为: http://wthrcdn.etouch.cn/weather_mini?citykey=城市代码局部城市代码对应: 北京 101010100天津 101030100上海 101020100浏览器返回的天津气温状况如下,该信息其实就是一个JSON字符串,格式化之后的样子如下所示: { "data": { "yesterday": { "date": "1日星期五", "high": "低温 17℃", "fx": "东北风", "low": "高温 8℃", "fl": "<![CDATA[<3级]]>", "type": "多云" }, "city": "北京", "forecast": [ { "date": "2日星期六", "high": "低温 14℃", "fengli": "<![CDATA[<3级]]>", "low": "高温 8℃", "fengxiang": "北风", "type": "小雨" }, ], "ganmao": "昼夜温差较大,较易产生感冒,请适当增减衣服。体质较弱的敌人请留神防护。", "wendu": "12" }, "status": 1000, "desc": "OK"}获取天气的次要代码如下: # cityCode 替换为具体某一个城市的对应编号# 1、发送申请,获取数据url = f'http://wthrcdn.etouch.cn/weather_mini?citykey={cityCode}'res = requests.get(url)res.encoding = 'utf-8'res_json = res.json()# 2、数据格式化data = res_json['data']city = f"城市:{data['city']}\n" # 字符串格式化的一种形式 f"{}" 通过字典传递值today = data['forecast'][0]date = f"日期:{today['date']}\n" # \n 换行now = f"实时温度:{data['wendu']}度\n"temperature = f"温度:{today['high']} {today['low']}\n"fengxiang = f"风向:{today['fengxiang']}\n"type = f"天气:{today['type']}\n"tips = f"贴士:{data['ganmao']}\n"result = city + date + now + temperature + fengxiang + type + tipsprint(result)二、界面的实现1、应用Qt Designer绘制窗口,保留为ui文件 ...

August 4, 2021 · 1 min · jiezi

关于python3.x:Python爬虫实战数据抓取并分析XZ销售记录数据发现了惊人的秘密

前言明天给大家用Python爬取京东的用户评估,通过数据分析实现数据可视化得出哪一种色彩的XZ最受女性欢送,废话不多说,间接开整~ 成果展现 流程剖析(鼠标右键或者键盘f12)关上开发者工具-network,在用户评估页面咱们发现浏览器有这样一个申请 通过剖析咱们发现次要用的参数有三个productId,page,pageSize。后两个为分页参数,productId是每个商品的id,通过这个id去获取商品的评估记录,所以咱们只须要晓得每个商品的productId就轻而易举的获取评估了。再来剖析搜寻页面的网页源代码 通过剖析咱们发现每个商品都在li标签中,而li标签又有一个data-pid属性,这个对应的值就是商品的productId了。 网站URL地址获取首先咱们须要在搜寻页面获取商品的id,为上面爬取用户评估提供productId。key_word为搜寻的关键字,这里就是【XZ】 import requestsimport re"""查问商品id"""def find_product_id(key_word): jd_url = 'https://search.jd.com/Search' product_ids = [] # 爬前3页的商品 for i in range(1,3): param = {'keyword': key_word, 'enc': 'utf-8', 'page': i} response = requests.get(jd_url, params=param) # 商品id ids = re.findall('data-pid="(.*?)"', response.text, re.S) product_ids += ids return product_ids将前三页的商品id放入列表中,接下来咱们就能够爬取评估了 咱们通过剖析preview发现获取用户评估这个申请响应的格局是一个字符串前面拼接了一个json(如下图),所以咱们只有将无用的字符删除掉,就能够获取到咱们想要的json对象了。 而在json对象中的comments的内容就是咱们最终想要的评估记录 """获取评论内容"""def get_comment_message(product_id): urls = ['https://sclub.jd.com/comment/productPageComments.action?' \ 'callback=fetchJSON_comment98vv53282&' \ 'productId={}' \ '&score=0&sortType=5&' \ 'page={}' \ '&pageSize=10&isShadowSku=0&rid=0&fold=1'.format(product_id, page) for page in range(1, 11)] for url in urls: response = requests.get(url) html = response.text # 删除无用字符 html = html.replace('fetchJSON_comment98vv53282(', '').replace(');', '') data = json.loads(html) comments = data['comments'] t = threading.Thread(target=save_mongo, args=(comments,)) t.start()在这个办法中只获取了前10页的评估的url,放到urls这个列表中。通过循环获取不同页面的评估记录,这时启动了一个线程用来将留言数据存到到MongoDB中。 ...

August 3, 2021 · 2 min · jiezi

关于python3.x:Python实用案例Python脚本Python实现批量下载百度图片

往期回顾Python实现主动监测Github我的项目并关上网页 Python实现文件主动归类 Python实现帮你抉择双色球号码 Python实现每日更换“必应图片”为“桌面壁纸” Python实现批量加水印 Python实现破译zip压缩包 前言明天咱们就利用python脚本实现批量下载百度图片。间接开整~ 成果展现 编写思路:1.获取图片的url链接首先,关上百度图片首页,留神下图url中的index 接着,把页面切换成传统翻页版(flip),因为这样有利于咱们爬取图片! 而后,右键查看网页源代码,间接(ctrl+F)搜寻 objURL 这样,咱们发现了须要图片的url了。 2.把图片链接保留到本地当初,咱们要做的就是将这些信息爬取出来。 注:网页中有objURL,hoverURL…然而咱们用的是objURL,因为这个是原图 正则表达式获取objURL results = re.findall('"objURL":"(.*?)",', html) 源码展现:1.获取图片url代码: # 获取图片url连贯 for i in range(int(pn)): # 1.获取网页 print('正在获取第{}页'.format(i+1)) # 百度图片首页的url # name是你要搜寻的关键词 # pn是你想下载的页数 url = 'https://image.baidu.com/search/flip?tn=baiduimage&ie=utf-8&word=%s&pn=%d' %(name,i*20) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.104 Safari/537.36 Core/1.53.4843.400 QQBrowser/9.7.13021.400'} # 发送申请,获取相应 response = requests.get(url, headers=headers) html = response.content.decode() # print(html) # 2.正则表达式解析网页 # "objURL":"http://n.sinaimg.cn/sports/transform/20170406/dHEk-fycxmks5842687.jpg" results = re.findall('"objURL":"(.*?)",', html) # 返回一个列表 # 依据获取到的图片链接,把图片保留到本地 save_to_txt(results, name, i)</pre>2.保留图片到本地代码: ...

August 3, 2021 · 1 min · jiezi

关于python3.x:Python实用案例Python脚本Python实现批量加水印

往期回顾Python实现主动监测Github我的项目并关上网页 Python实现文件主动归类 Python实现帮你抉择双色球号码 Python实现每日更换“必应图片”为“桌面壁纸” 前言:明天咱们就利用python脚本实现批量加水印。间接开整~ 成果展现 有时候,为了爱护版权,须要给作品中的图片加上水印。 一种是把水印(logo)加在图片的一个角落,就像有的是公众号会在后盾把水印关上。 更厉害的一种是,水印在整个图上有很多,有个轻微的透明度,更平安。 PYTHON自动化 明天就来带大家,用Python给图片批量加上水印。有的小伙伴可能会说,网上也有很多工具有相似的性能,何必反复造轮子,被我猜到了吧。 既然如此,那就先看看用Python做这个工具的特点吧: 能够设置字体(大小)能够设置角度能够设置透明度能够设置色彩能够批量解决能够设置水印的距离这个工具,其实是一个大神开源在Github上的我的项目,我只是个搬运工。 贴个地址: https://github.com/2Dou/water...代码能够从Github上下载,也可在“文末”找到下载方式。 重要的事说三遍: 记得把文件夹放在英文目录下 、记得把文件夹放在英文目录下 、记得把文件夹放在英文目录下 下载之后的目录构造是这样的: fontinputoutputmarker.pyREADME.md“字体”文件夹,寄存的是“青鸟华光简琥珀.ttf ” “input”文件夹,寄存的是你要解决的图片,那么“output”天然就是输入的后果了 “marker.py”是实现性能的脚本文件 “README.md”是一个介绍文档 值得注意的有两点: 1、把“青鸟华光简琥珀.ttf ” 改为 “bird.ttf”, 名字不重要,只有是换成英文。另外,你也能够把你本地的字体(你喜爱的)替换过去。 2、在“marker.py”脚本中,把对应的字体名称替换掉。 看看成果 到这里,能够运行试试了。 在“marker.py”的同级目录下,关上Terminal/cmd,输出如下命令: python marker.py -f ./input/test.png -m 天作之程-f参数,输出图片的地位(能够是具体的一张照片,也能够是整个文件夹)-m参数,你要增加的内容另外,上边提到的其余性能参数: -o 参数,指定输入水印文件的地位,默认为output文件夹。-c 参数,指定水印的色彩,默认值为黄色,#8B8B1B-s 参数,指定水印之间的空隙,默认值为75。-a 参数,指定水印的旋转角度,默认值30度。--size参数,指定水印文本字体大小,默认值为50。--opacity参数,指定透明度,默认为0.15,数值越小越通明。这里放一个我感觉比拟难受的参数: python marker.py -f ./input -m 天作之程 -c#232862 --opacity 0.05如果感觉色彩不够完满,能够从上面的链接找到色彩对应的16进制,copy过去即可。 https://www.sioe.cn/yingyong/...文章到这里就完结了,感激你的观看,Python实用脚本系列,下篇文章分享Python破译zip压缩文件 为了感激读者们,我想把我最近珍藏的一些编程干货分享给大家,回馈每一个读者,心愿能帮到你们。 干货次要有: ① 2000多本Python电子书(支流和经典的书籍应该都有了) ② Python规范库材料(最全中文版) ③ 我的项目源码(四五十个乏味且经典的练手我的项目及源码) ④ Python根底入门、爬虫、web开发、大数据分析方面的视频(适宜小白学习) ⑤ Python学习路线图(辞别不入流的学习) ...

July 31, 2021 · 1 min · jiezi

关于python3.x:Python实用案例Python脚本Python实现每日更换必应图片为桌面壁纸

往期回顾Python实现主动监测Github我的项目并关上网页 Python实现文件主动归类 Python实现帮你抉择双色球号码 前言:明天咱们就利用python脚本实现每日更换“必应图片”为“桌面壁纸”。间接开整~ 成果展现 思路整顿1、通过网页,获取图片地址 2、保留图片到绝对路径 3、设置该绝对路径所指向的图片为壁纸 4、批处理壁纸主动切换 须要用到的模块如下: import urllib.requestimport requestsimport os.pathimport ctypes第一、获取图片地址这个函数次要通过requests模块,依据必应的网页地址,获取到当日图片的最终img地址。 # 申请网页,跳转到最终 img 地址def get_img_url(raw_img_url="https://area.sinaapp.com/bingImg/"): r = requests.get(raw_img_url) img_url = r.url # 失去图片文件的网址 print('img_url:', img_url) return img_url第二、保留图片到本地这个函数的作用就是把图片保留到你本人设置的一个目录下,并返回当前目录的相对地址。 def save_img(img_url, dirname): # 保留图片到磁盘文件夹dirname中 try: if not os.path.exists(dirname): print('文件夹', dirname, '不存在,从新建设') # os.mkdir(dirname) os.makedirs(dirname) # 取得图片文件名,包含后缀 basename = "bing.jpg" # 拼接目录与文件名,失去图片门路 filepath = os.path.join(dirname, basename) # 下载图片,并保留到文件夹中 urllib.request.urlretrieve(img_url, filepath) except IOError as e: print('文件操作失败', e) except Exception as e: print('谬误 :', e) print("Save", filepath, "successfully!") return filepath第三、设置该绝对路径所指向的图片为壁纸通过之前取得的图片所在的绝对路径,把该图片设置为桌面壁纸。 ...

July 30, 2021 · 1 min · jiezi

关于python3.x:Python实用案例Python脚本Python实现帮你选择双色球号码

往期回顾Python实现主动监测Github我的项目并关上网页 Python实现文件主动归类 前言:明天咱们就利用python脚本实现帮你抉择双色球号码。间接开整~ 开发工具:python版本: 3.9.6 函数: random 成果展现 原理简介双色球,顾名思义,就是两种色彩的球,红色和蓝色。 红球从1-33中取出6个,篮球从1-16取出1个。留神,红球为不放回采样,也就是不能有反复的。 那么,带大家用python来抉择双色球号码。 其实很简略,只用到一个随机数模块。先说红球共6个,每次从1-33个数中随机抉择一个,且不反复的状况下,增加到一个列表中;蓝球从1-16个球中随机抉择一个即可。源码展现import randomred_ball = []while True: # 生成一位随机数 a = random.randint(1, 34) # 防止反复 if a not in red_ball: # 把不反复的数字,增加到列表 red_ball.append(a) # 返回6个不反复的红球 if len(red_ball) == 6: print("红球:", red_ball) break# 生成蓝球blue_ball = random.randint(1, 17)print("蓝球:", blue_ball)# 运行后果:红球: [17, 28, 24, 19, 29, 23]蓝球: 9运行下面程序,就会随机生成一组数据。 不过你说,这样选出来的数据有啥用,真的也只能在平淡的生存多了那么一丝期待。 文章到这里就完结了,感激你的观看,Python实用脚本系列,下篇文章分享更换“必应图片”为“桌面壁纸” 为了感激读者们,我想把我最近珍藏的一些编程干货分享给大家,回馈每一个读者,心愿能帮到你们。 干货次要有: ① 2000多本Python电子书(支流和经典的书籍应该都有了) ② Python规范库材料(最全中文版) ③ 我的项目源码(四五十个乏味且经典的练手我的项目及源码) ④ Python根底入门、爬虫、web开发、大数据分析方面的视频(适宜小白学习) ⑤ Python学习路线图(辞别不入流的学习) ⑥ 两天的Python爬虫训练营直播权限 ...

July 29, 2021 · 1 min · jiezi

关于python3.x:Python实用案例Python脚本Python实现自动监测Github项目并打开网页

前言:明天咱们就利用Python脚本实现Github我的项目的更新,揭示形式是邮箱。间接开整~ 我的项目地址: https://github.com/kenwoodjw/python_interview_question 实现过程获取数据 Github官网提供了具体的数据接口,并且数据是以Json字符串的形式保留的。我的项目的数据地址: https://api.github.com/repos/kenwoodjw/python_interview_question 每一个我的项目的数据地址,相似于本地磁盘目录。 咱们通过数据接口的url地址,就能够获取到更新工夫。 import request# 1.Github我的项目及API接口数据api = 'https://api.github.com/repos/kenwoodjw/python_interview_question'web_page = "https://github.com/kenwoodjw/python_interview_question定时监测数据变动 关上网页 设置一个循环,每隔10分钟获取一次update_at的数据,如果前后工夫不统一,阐明数据更新,并主动关上我的项目主页。 while True: all_info = requests.get(api).json() cur_update = all_info['updated_at'] print(cur_update) # 假如第一次运行之前,不晓得上次的更新工夫 # 如果last_update 为 none,会执行上面的语句,把以后的工夫给到上次工夫 if not last_update: last_update = cur_update # 第一次两个工夫相等,不会执行 # 假如10分钟后,cur_update更新,那么就会主动关上网页 # 接下来,把 以后工夫 赋值 给上次工夫 # 开始新一轮的监测 if last_update < cur_update: webbrowser.open(web_page) last_update = cur_update # 距离 10分钟,再次while循环,察看新的更新工夫是否发生变化 time.sleep(600)文章到这里就完结了,感激你的观看,Python实用脚本系列,下篇文章分享Python生成双色球 为了感激读者们,我想把我最近珍藏的一些编程干货分享给大家,回馈每一个读者,心愿能帮到你们。 干货次要有: ① 2000多本Python电子书(支流和经典的书籍应该都有了) ② Python规范库材料(最全中文版) ...

July 28, 2021 · 1 min · jiezi

关于python3.x:记一次直播录屏

记一次直播录屏部署前提: 装置ossutil 工具装置ffmpegCentos8装置ffmpegrequirement安装包 其中装置opencv-python,还须要装置yum install mesa-libGL.x86_64 certifi==2021.5.30chardet==4.0.0click==8.0.1colorlog==5.0.1decorator==4.4.2Flask==2.0.1idna==2.10imageio==2.9.0imageio-ffmpeg==0.4.4importlib-metadata==4.6.0itsdangerous==2.0.1Jinja2==3.0.1MarkupSafe==2.0.1moviepy==1.0.3numpy==1.21.0opencv-python==4.5.2.54Pillow==8.3.1proglog==0.1.9redis==3.5.3requests==2.25.1tqdm==4.61.2typing-extensions==3.10.0.0urllib3==1.26.6waitress==2.0.0Werkzeug==2.0.1zipp==3.4.1ffmpeg根底命令记录录屏 ffmpeg -i %s -c:v copy -c:a copy %s -y -loglevel error " % (flv_url, absolute_file_path) 截取一段视频 ffmpeg -i {first_ts_file} -ss 00:00:00.50 -t 00:00:00.10 -c:v copy -c:a copy {first_file} 将图片制作成一段定长的视频 ffmpeg -loop 1 -i {file_image} -pix_fmt yuv420p -vcodec libx264 -b:v 600k -r:v 25 -preset medium -crf 30 -s 1080x1920 -t {interrupt_middle_time} {interrupt_middle_ts_file} 在这里当这个视频作为第一个视频去拼接其余视频的时候,会导致合并后的视频无声的问题。可怕的不止如此,如果放在两头地位,下一个的视频音轨还会跑到两头这个没有音轨的视频中。对ffmpeg也不相熟,不晓得有什么优雅的解决办法,我是退出空白音轨来解决的。 将图片制作成一段定长带有空白音轨的视频 ffmpeg -loop 1 -i {file_image} -f lavfi -i anullsrc=cl=stereo:r=44100 -pix_fmt yuv420p -vcodec libx264 -acodec aac -absf aac_adtstoasc -b:v 600k -preset medium -crf 30 -s 1080x1920 -tune stillimage -shortest -t {interrupt_image_time / 2} {interrupt_begin_ts_file}视频合并 ...

July 11, 2021 · 1 min · jiezi

关于python3.x:Python3编程实战Tetris机器人ORM

系列文章入口《Python3编程实战Tetris机器人》 设计思路咱们通用的ORM,基本模式都是想要脱离数据库的,简直都在编程语言层面建设模型,由程序去与数据库打交道。尽管脱离了数据库的具体操作,但咱们要建设各种模型文档,用代码去写表之间的关系等等操作,让初学者一时如坠云雾。我的做法是把逻辑退出到Python的字典中,程序将对象主动映射成为规范的SQL查问语句。只有咱们了解了规范的SQL语言,咱们就可能实现数据库查问操作。 智能查问形式设计查问保留字:page, size, sort, search, lks, ins, ors, count, sum, grouppage, size, sort, 分页排序查问示例: dao = BaseDao()rs = dao.select("users",{"page": 1, "size":10, "sort":"age desc"})print(rs)生成sql: SELECT * FROM users ORDER BY age desc LIMIT 0,10search, 含糊查问切换参数,不提供时为准确匹配提供字段查问的准确匹配与含糊匹配的切换。```dao = BaseDao()rs = dao.select("users",{"username": "john", "password":"123", "search":"1"})print(rs)生成sql: SELECT * FROM users WHERE username like '%john%' and password like '%123%'```ins, lks, ors这是最重要的三种查问形式,如何找出它们之间的共同点,缩小冗余代码是要害。 ins, 数据库表单字段in查问,一字段对多个值,例: 查问示例: dao = BaseDao()rs = dao.select("users",{"ins":["age", 11,22,26]})print(rs)生成sql: SELECT * FROM users WHERE age in ( 11,22,26 )ors, 数据库表多字段准确查问,or连贯,多个字段对多个值,例: 查问示例: ...

July 5, 2021 · 2 min · jiezi

关于python3.x:Python3编程实战Tetris机器人数据库操作

系列文章入口《Python3编程实战Tetris机器人》 设计思路将用户手动玩和AI主动玩游戏的历史记录下来,存入数据库,供前面进行剖析。为了不依赖某个特定的数据系统,设计了一个通用数据库操作接口,以不便在利用层面切换不同的数据库。 接口设计class BaseDao(object): def select(self, tablename, params={}, fields=None): # 查问接口,参数:数据表名;查问参数(ORM规定融入字典中,请参看下一篇日志);返回数据字段 fields = [] if fields == None else fields # Python的默认参数行为很是不同,会记录上一次调用的后果,有点象其它语言中的动态变量 return dbhelper.select(tablename, params, fields) # 真正的查问实现,dbhelper是针对特定数据库的接口实现 def insert(self, tablename, params={}, fields=[]): # 新增接口,CURD函数的参数模式统一,这种设计不便作rest微服务时,由http的不同拜访形式间接抉择后盾操作方法 if '_id_' in params and len(params) < 2 or '_id_' not in params and len(params) < 1: # 要求提供_id_,约定_id_为所有表的主键 return {"code": 301, "err": "The params is error."} return dbhelper.insert(tablename, params) def update(self, tablename, params={}, fields=[]): if '_id_' not in params or len(params) < 2: return {"code": 301, "err": "The params is error."} return dbhelper.update(tablename, params) def delete(self, tablename, params={}, fields=[]): if '_id_' not in params: return {"code": 301, "err": "The params is error."} return dbhelper.delete(tablename, params) def querySql(self, sql, values = [], params = {}, fields = []): # 手写查问接口 return dbhelper.querySql(sql, values, params, fields) def execSql(self, sql, values = []): # 手写非查问接口 return dbhelper.exec_sql(sql, values) def insertBatch(self, tablename, elements : List): # 批量写入接口 return dbhelper.insertBatch(tablename,elements) def transGo(elements = [], isAsync = False): # 事务接口,待实现 pass具体实现(Sqlit3)首先实现了对Sqlit3的操作接口。 ...

July 2, 2021 · 3 min · jiezi

关于python3.x:Python3编程实战Tetris机器人游戏暂停

系列文章入口《Python3编程实战Tetris机器人》 设计思路游戏暂停性能比较简单,次要是管制gameRunningStatus变量的值与界面的管制对立起来,游戏暂停了,键盘的响应也要进行。另,gameRunningStatus变量的扭转也不能间接操作,需生成一个暂停命令单元,送入队列中,由工作工作线程去解决。 具体实现界面管制开始按钮会在 “Start”、“Rause”和“Resume”之间切换。 def btnStartClicked(self): if self.game.getGameRunningStatus() == 0: # 点击时游戏处于未开始状态 self.btnStartVar.set("Pause") self.game.start() elif self.game.getGameRunningStatus() == 1: # 点击时游戏处于游戏中 self.btnStartVar.set("Resume") self.game.pause() elif self.game.getGameRunningStatus() == 5: # 点击时游戏处于暂停状态 self.btnStartVar.set("Pause") self.game.resume() self.gameCanvas.focus_set() # 设置游戏空间为以后流动控件游戏完结时,复原初始状态 self.app.setStartButtonText("Start")暂停操作def pause(self): opQueue.put(("pause",5))复原操作游戏处于暂停中,所以间接批改变量值,没有设计命令单元了。 def resume(self): self.gameRunningStatus = 1 self.canvas.after(self.gameSpeedInterval * (0 if self.isAutoRunning else 1), self.tickoff)每一个工作单元都是一个二元元组(不便数据解构),第一个是字符串,为命令;第二个是元组,是数据包(也按不便解构的形式去设计),由每个命令自行定义。 工作线程减少暂停解决...elif cmd == "pause": self.gameRunningStatus = data...键盘响应革新def processKeyboardEvent(self, ke): if self.game.getGameRunningStatus() == 1 and self.game.isAutoRunning == 0: if ke.keysym == 'Left': opQueue.put(('Left',())) ...我的项目地址https://gitee.com/zhoutk/ptetris或https://github.com/zhoutk/ptetris运行办法1. install python3, git2. git clone https://gitee.com/zhoutk/ptetris (or download and unzip source code)3. cd ptetris4. python3 tetrisThis project surpport windows, linux, macOson linux, you must install tkinter first, use this command: sudo apt install python3-tk相干我的项目曾经实现了C++版,我的项目地址: ...

June 24, 2021 · 1 min · jiezi

关于python3.x:Python3编程实战Tetris机器人多线程问题

系列文章入口《Python3编程实战Tetris机器人》 发现问题在测试过程中,发现程序出错,但敞开定时器,不进行主动着落就不会有问题。起因是Timer会新开一个线程,线程和主线会产生资源抵触。 解决方案首先想到的是加锁,游戏逻辑很简略,加锁应该很容易解决问题。但不论我粗粒度加,还是尽量细粒度加,最初都会死锁。最初进行打印,发现程序停在了tkinter.Canvas.move处,集体认为这是tkinter的bug。 此路不通,换个思路。开一个工作线程,来实现所有的操作,主线程与定时器操作,都只是往工作线程中提交工作。也就是只让一个工作线程来做工作,这样就把资源抵触的问题避开了。 加锁加锁计划剖析 键盘响应加锁tickLock[0] = Truewith curTetrisLock: print("-------+++---00000000--- get lock", tickLock) if ke.keysym == 'Left': self.game.moveLeft() if ke.keysym == 'Right': self.game.moveRight() if ke.keysym == 'Up': self.game.rotate() if ke.keysym == 'Down': self.game.moveDown() if ke.keysym == 'space': self.game.moveDownEnd()print("-------+++---00000000--- lose lock", tickLock)定时器响应加锁def tickoff(self): if self.gameRunningStatus == 1: if not tickLock[0]: with curTetrisLock: print("------------------ get lock", tickLock[1]) self.moveDown() print("================== lose lock", tickLock[1]) self.tick = Timer(self.gameSpeedInterval / 1000, self.tickoff) self.tick.start()问题定位程序最初停在了Block类中的tkinter.Canvas.move处,每次都由定时器触发,无奈开释。有趣味的同学能够到我的项目中,切换到lockbug分支去钻研,我写了很多打印输出不便问题定位。 减少工作线程工作单元设计新增一个Queue,键盘响应与定时器响应往队列中减少工作单元,工作线程逐个解决这些工作。工作单元如下设计: ("cmd",(data))每一个工作单元都是一个二元元组(不便数据解构),第一个是字符串,为命令;第二个是元组,是数据包(也按不便解构的形式去设计),由每个命令自行定义。 ...

June 22, 2021 · 1 min · jiezi

关于python3.x:Python3编程实战Tetris机器人game类

系列文章入口《Python3编程实战Tetris机器人》 game类游戏逻辑管制类,是界面与Tetris类之间的粘合者,承受界面的鼠标及键盘事件,操作Tetris类,实现游戏逻辑。单个方块的操作,在Tetris中曾经实现,game类次要是实现消行算法、新方块的产生、游戏速度管制等。 设计思路消层算法简略的解决就是发现一行,打消一行。本我的项目应用一点技巧,先找出所有可打消行,把行号存入数组中,一次性打消。游戏速度的管制,应用定时器来实现,但发现python的定时器与其它语言有些差异,会一直产生新的定时器对象,开始感觉有些不对劲,但也没有器重。起初确认,这会产生内存透露,后应用tkinter.after替换了。 相干常数SCORES = (0,1,3,7,10) # 消层分值设定STEPUPSCORE = 50 # 每增长50分,速度放慢一个等级STEPUPINTERVAL = 100 # 每增长一个等级,定时器间隔时间缩小100毫秒具体实现游戏状态变量game.gameRunningStatus 0 : 游戏未开始1 : 手动游戏2 : 游戏回放5 : 游戏暂停开始游戏def start(self): self.gameRunningStatus = 1 self.gameSpeedInterval = 1000 # 初始游戏速度 self.gameSpeed = 1 # 游戏速度等级 self.gameLevels = 0 # 消层数 self.gameScores = 0 # 总得分 self.app.updateGameInfo(1,0,0) # 初始化界面信息 self.canvas.delete(ALL) # 清空游戏空间 self.nextCanvas.delete(ALL) # 下一方块空间清空 initGameRoom() # 初始化游戏空间数据 self.tetris = Tetris(self.canvas, 4, 0, random.randint(0,6)) # 随机生成第一个方块 for i in range(random.randint(0,4)): # 旋转随机次数,方块出场式 self.tetris.rotate() self.nextTetris = Tetris(self.nextCanvas, 1, 1, random.randint(0,6)) # 随机生成下一方块 for i in range(random.randint(0,4)): # 下一方块初始状态(随机) self.nextTetris.rotate() self.tick = Timer(self.gameSpeedInterval / 1000, self.tickoff) # 管制游戏速度定时器 self.tick.start()生成下一方块游戏管制次要函数,在方块着落到底部后,进行消层、统计得分、速度等级断定、游戏是否完结断定以及将下一方块移入游戏空间并再生成一个方块显示在下一方块显示空间中。 ...

June 21, 2021 · 3 min · jiezi

关于python3.x:Python3编程实战Tetris机器人移动与旋转

系列文章入口《Python3编程实战Tetris机器人》 方块挪动为了不便,设计了相对定位函数,变相对运动形式为相对定位。 方块相对定位函数咱们Block类中,对blog的挪动应用的是tkinter.move函数,该函数提供的是绝对间隔形式,咱们须要计算出位移差。该办法相当于把绝对间隔挪动形式,变成了方块的相对定位函数,所有挪动操作都应用这个函数。 def relocate(self, x, y): for block in self.objs: # 遍历方块的block block.relocate(x - self.x, y - self.y) # 挪动操作 self.x = x self.y = y方块左移def moveLeft(self): if self.canPlace(self.x - 1, self.y): # 判断是否能左移 self.relocate(self.x - 1, self.y) # 挪动 return True else: return False方块右移def moveRight(self): if self.canPlace(self.x - 1, self.y): # 判断是否能右移 self.relocate(self.x + 1, self.y) # 挪动 return True else: return False方块下移方块下移,须要判断是否曾经到底,到底后,方块地位将固定下来。 def moveDown(self): if self.canPlace(self.x, self.y + 1): # 判断是否能下移 self.relocate(self.x, self.y + 1) # 下移 return True else: # 曾经到底 for i in range(TETRISDIMENSION): for j in range(TETRISDIMENSION): if self.data[i][j]: # 固定方块,改游戏空间格局 GameRoom[self.y + i][self.x + j] = 1 return False方块旋转方块旋转,本质上是矩形的旋转,咱们设定按一次方向上键,方块进行一次顺时针90度旋转。 ...

June 20, 2021 · 1 min · jiezi

关于python3.x:Python3编程实战Tetris机器人Tetris类

系列文章入口《Python3编程实战Tetris机器人》 Tetris类组合Block类,实现俄罗斯方块的绘制及挪动、旋转等所有操作。这是Tetris游戏的业务外围,第一步先实现手动玩的需要,当前AI主动玩时,还会革新这个类。在所有的逻辑外面,特地留神旋转(rotate)操作,前面解决的不少的bug被证实都是因为rotate操作思考不全面所引起的。 设计思路Tetris类通过组合Block类来实现屏幕的绘制,并与tkinter库进行解耦。因为tkinter库的设计,咱们的界面应用了两个Canvas来别离实现游戏空间和下一方块的显示,因而一个方块有可能显示在不同的Canvas中。当一个方块搁置后,要从nextCanvas中取出下一个方块,搁置到游戏空间的上方。这个操作我没有找到简略的办法来施行跨Canvas挪动元件。我的实现办法是,从新在游戏空间生成一个与nextCanvas中一样的方块,因为我每一个方块的初始状态是固定的,只是让它实现了几次随机的旋转,因而我只需查问next Tetris中的形态和旋转次数就能够复制了。 相干常数GameRoom = [[0 for i in range(12)] for i in range(22)] # 游戏空间定义 10x20TETRISAHPES = ( # 方块的状态定义 (1, 1, 1, 1), # 方块一共有六种状态 (0, 1, 1, 1, 0, 1), # 其它状态都能够通过几次旋转来失去 (1, 1, 1, 0, 0, 0, 1), # 我定义旋转为顺时针旋转 (0, 1, 1, 0, 0, 1, 1), # 每一个方块的状态最多旋转四次就回到初始状态 (1, 1, 0, 0, 0, 1, 1), (0, 1, 1, 0, 1, 1), (0, 1, 0, 0, 1, 1, 1))TETRISCOLORS = ( # 方块状态与色彩的绑定 "red", "magenta", "darkMagenta", "gray", "darkGreen", "darkCyan", "darkBlue")具体实现构造函数def __init__(self, canvas, x, y, shape): self.x = x # 方块在游戏空间的横坐标地位 1-10 self.y = y # 方块在游戏空间的纵坐标地位 1-20 self.canvas = canvas # 方块绘制的空间 self.objs = [] # 组合Block类对象 self.rotateCount = 0 # 方块旋转次数 self.shape = shape # 方块初始状态 self.color = TETRISCOLORS[shape] # 方块色彩 self.data = [ # 方块状态数据 [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0] ] curShape = TETRISAHPES[shape % len(TETRISAHPES)] for i, b in enumerate(curShape): # 绘制方块初始状态 if b: self.data[1 + i // TETRISDIMENSION][i % TETRISDIMENSION] = 1 # 状态数据初始化 self.objs.append(Block(canvas, self.x + i % TETRISDIMENSION, \ # 组合Block并绘制 self.y + 1 + i // TETRISDIMENSION, self.color))判断游戏空间某个地位是否有Block这个函数很重要,判断是否越界、方块是否能挪动都须要它。游戏空间比理论空间大一圈,最外围数据都初始化为1,作为越界哨兵。 ...

June 19, 2021 · 2 min · jiezi

关于python3.x:为什么爬虫工程师应该有一些基本的后端常识

明天在粉丝交换群外面,有个同学说他发现了Requests的一个 bug,并修复了它: 聊天记录中对应的图片为: 看到这个同学的截图,我大略晓得他遇到了什么问题,以及为什么会误认为这是 Requests 的 bug。 要解释这个问题,咱们须要首先明确一个问题,那就是 JSON 字符串的两种显示模式和json.dumps的ensure_ascii参数。 假如咱们在 Python 外面有一个字典: info = {'name': '青南', 'age': 20}当咱们想把它转成 JSON 字符串的时候,咱们可能会这样写代码: import jsoninfo = {'name': '青南', 'age': 20}info_str = json.dumps(info)print(info_str)运行成果如下图所示,中文变成了 Unicode 码: 咱们也能够减少一个参数ensure_ascii=False,让中文失常显示进去: info_str = json.dumps(info, ensure_ascii=False)运行成果如下图所示: 这位同学认为,因为{"name": "\u9752\u5357", "age": 20}和{"name": "青南", "age": 20}从字符串角度看,显然不相等。而 Requests 在 POST 发送数据的时候,默认是没有这个参数,而对json.dumps来说,省略这个参数等价于ensure_ascii=True: 所以实际上Requests在 POST 含有中文的数据时,会把中文转成 Unicode 码发给服务器,于是服务器基本就拿不到原始的中文信息了。所以就会导致报错。 但实际上,并不是这样的。我经常跟群里的同学说,做爬虫的同学,应该要有一些根本的后端常识,才不至于被这种景象误导。为了阐明为什么下面这个同学的了解是谬误的,为什么这不是 Requests 的 bug,咱们本人来写一个含有 POST 的服务,来看看咱们POST 两种状况的数据有没有区别。为了证实这个个性与网络框架无关,我这里别离应用Flask、Fastapi 、Gin 来进行演示。 首先,咱们来看看Requests 测试代码。这里用3种形式发送了 JSON 格局的数据: ...

June 19, 2021 · 2 min · jiezi

关于python3.x:Python3编程实战Tetris游戏block类

系列文章入口《Python3编程实战》 block类在屏幕上绘制小方块,以及方块的挪动与革除。依据tkinter库的函数特点,抉择canvas.create_rectangle进行方块绘制,canvas.move挪动方块,canvas.delete革除方块。画布操作函数只应用了上述三个。 设计思路tkinter库提供的函数是组件式的,不是画一个图形,而是生成一个图元对象。能够取得这个图元的“句柄”,而后对其进行挪动,删除。因为block类设计为结构、定位和革除三个办法,就足够实现咱们的Tetris游戏。 相干常数TETRISDIMENSION = 4 # Tetris方块维度BLOCKSIDEWIDTH = 30 # 最小方块边长设定HALFBLOCKWIDTH = BLOCKSIDEWIDTH // 2 # 最小方块边长一半CANVASOFFSET = 4 # 绘制偏移量,与游戏边框的间隔TETRISCOLORS = ( # Tetris方块的色彩设定 "red", "magenta", "darkMagenta", "gray", "darkGreen", "darkCyan", "darkBlue")具体实现构造函数def __init__(self, canvas, x, y, color = "red") -> None: self.canvas = canvas # 所在画布,gameCanvas or nextCanvas self.x = x # 横会标地位,游戏空间地位,x > 0 and x < 11 self.y = y # 纵会标地位,游戏空间地位,y > 0 and y < 21 self.obj = canvas.create_rectangle((x - 1) * \ # 绘制小正方形,并存储,供革除用 BLOCKSIDEWIDTH + CANVASOFFSET, (y - 1) * \ # 游戏坐标与空间坐标对应,起始点 BLOCKSIDEWIDTH + CANVASOFFSET, \ x * BLOCKSIDEWIDTH + CANVASOFFSET, \ # 完结点 y * BLOCKSIDEWIDTH + CANVASOFFSET, \ fill = color, outline = "yellow") # 填充色彩与边框色彩挪动函数def relocate(self, detaX, detaY): # 参数为挪动间隔差 self.canvas.move(self.obj, \ # 挪动到新地位 detaX * BLOCKSIDEWIDTH, \ detaY * BLOCKSIDEWIDTH) self.x += detaX # 存储新的地位坐标 self.y += detaY革除函数Tetris中组合了block,屏幕上的革除由block本人实现。 ...

June 9, 2021 · 1 min · jiezi

关于python3.x:Python3编程实战Tetris游戏界面设计

界面设计本我的项目重视算法实现,为了安装简单且具备强跨平台性,所以抉择python内置的tkinter。这个界面库是有些问题,比方前面发现其与线程锁配合有问题,会莫名死掉。我的项目中的lockbug分支,我曾经把问题定位了,进行了一系列的日志输入,有趣味的同学能够去钻研一下具体问题。这个问题能够避开,本我的项目应用的界面个性很少,我的主张够用即可。 设计思路应用两个canvas来显示方块,一个是游戏空间,另一个是下一方块显示。因为界面比较简单,分成三局部,一是游戏空间,二是下一方块显示,三是信息即操作按钮。这三大块间接应用place相对定位,第三大块应用frame对Label,Button等元素进行组合。 界面成果 具体实现窗口设定def start(): root = Tk() root.title("Tetris") root.geometry('470x630') # 窗口大小,两头是字母x示意乘号 root.resizable(0, 0) # 窗口大小固定 App(root) root.mainloop()两个canvasfrom tkinter import *from tkinter import ttk # 常数CANVASOFFSET,目标是留一点边框空隙,在不同的操作系统上体现不统一,用空隙协调self.gameCanvas = Canvas(root, bg='black', height=600 + CANVASOFFSET * 2, width=300 + CANVASOFFSET * 2)self.gameCanvas.place(x=12, y=10) # 相对定位 # 父窗口 背景设为彩色self.nextCanvas = Canvas(root, bg='black', height=120 + CANVASOFFSET * 2, width=120 + CANVASOFFSET * 2)self.nextCanvas.place(x = 330, y = 10)信息操作单元应用frame来组合画布对象,应用anchor形式来布局,这块不能用side形式,留神两种形式的区别。 frame = Frame(root)frame.place(x = 330, y = 160)Label(frame, text = "SPEED:").pack(anchor="w") # 应用anchor形式布局self.speedVar = StringVar() # 游戏速度显示变量,留神这有圆括号,与前面的下拉框比拟speed = Label(frame, height=1, width=12, relief=SUNKEN, bd=1, textvariable=self.speedVar)speed.pack(anchor="w")复选框与按钮: ...

June 8, 2021 · 1 min · jiezi

关于python3.x:Python3编程实战Tetris游戏项目结构

我的项目构造我的项目的构造如下,以目录模式的模块包来组织代码,同时反对以目录或包来执行,两种形式具备对立入口。 \ptetris|---- .editorconfig|---- .gitignore|---- .vscode| |---- launch.json| |---- settings.json|---- LICENSE.rst|---- README.md|---- tetris| |---- app.py| |---- block.py| |---- config.py| |---- game.py| |---- tetris.py| |---- __init__.py| |---- __main__.py实现细节咱们的程序位于tetris目录(包)中,能够作为一个文件夹来执行: python tetris也能够作为一个包(Package)来执行: python -m tetris__init__.py若要 python 将一个文件夹作为 Package 看待,那么这个文件夹中必须蕴含一个名为 __init__.py 的文件,即便它是空的。咱们在这个文件中定义main(),作为软件的对立入口。 from tetris.app import start # 这个tetris目录下的文件都位于tetris包中了def main(): print("Hi I'm Tetris!") start() #实在入口在app.py中__main__.py若要 python 运行一个文件夹,这个文件夹中必须蕴含一个名为 __main__.py 的文件在__main__.py中调用__init__.py中的main(),对立程序入口。 import tetristetris.main()这时以包形式运行没有问题,但以目录形式运行会出错: Traceback (most recent call last): File "C:\Users\zhoutk\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 197, in _run_module_as_main return _run_code(code, main_globals, None, File "C:\Users\zhoutk\AppData\Local\Programs\Python\Python39\lib\runpy.py", line 87, in _run_code exec(code, run_globals) File "d:\codes\ptetris\tetris\__main__.py", line 7, in <module> import tetris File "d:\codes\ptetris\tetris\tetris.py", line 2, in <module> from tetris.config import *ModuleNotFoundError: No module named 'tetris.config'; 'tetris' is not a package起因在于,sys.path 的第一个搜寻门路,一个是包,一个是空字符串。对于 python -m tetris 的调用形式来说,因为 __init__.py 被当时载入,此时 python 解释器曾经晓得了这是一个包,因而以后门路(空字符串)被蕴含在 sys.path 中。而后再调用 __main__.py ,这时 import pkg 这个包就没有问题了。 而对于 python tetris的调用形式来说,python 解释器并不知道本人正在一个 Package 上面工作。默认的,python 解释器将 __main__.py 的以后门路 tetris退出 sys.path 中,而后在这个门路上面寻找 tetris这个模块,因而出错。 在__main__.py结尾退出如下代码,就能解决这个问题: ...

June 4, 2021 · 1 min · jiezi

关于python3.x:Python3编程实战Tetris游戏序

背景本系列文章,应用Python3一步步记录Tetris游戏的编写全过程,游戏性能包含手动游戏、游戏回放(数据库操作)、主动游戏(AI机器人)。曾经实现C++版本,Qt5之QGraphicsItem编写Tetris俄罗斯方块游戏。 布局我的项目构造与界面设计block类,最小方块定义tetris类,俄罗斯方块定义tetris方块的挪动与旋转game类,游戏流程管制实现游戏基本功能,反对游戏暂停为数据查问封装json设计通用数据库操作封装,首先应用sqlite3设计ORM实现主动查问存储历史数据,实现游戏回放简略AI机器学习,改良AI设计思路该游戏尽量不应用第三方库,次要重视算法,因而界面库抉择python内置的tkinter。设计思维也采纳传统的形式,用一个二维数组来管制游戏空间,相似迷宫的形式。抉择这种形式有一个益处是,游戏的数据直观存在,容易获取。 效果图 我的项目地址https://gitee.com/zhoutk/ptetris或https://github.com/zhoutk/ptetris运行办法1. install python3, git2. git clone https://gitee.com/zhoutk/ptetris (or download and unzip source code)3. cd ptetris4. python3 tetrisThis project surpport windows, linux, macOson linux, you must install tkinter first, use this command: sudo apt install python3-tk相干我的项目曾经实现了C++版,我的项目地址: https://gitee.com/zhoutk/qtetris

June 4, 2021 · 1 min · jiezi

关于Python之路:Python之路day05字典增删改查keysvaluesitems

前言时刻上午讲的好多呀,信息量有点大,次要讲字典 来来总结: 明天次要讲了字典的创立、增:setdefault、删:pop、del、改、查:get 以及dic.keys()、 dic.values()、 dic.items() 字典字典的特点是由键值对组成,其中键是可哈希的,个别是int、str,而值能够是任意数据类型,不可哈希。长处是查问速度快,然而存储空间较大,典型的用空间复杂度换工夫。 从3.6X版本以来,字典默认有序,程序依照字典建设前后程序。 1、创立字典# 1、最罕用dic = {'name': 'come', 'hobby': [1, 2, 3], 'age': 18} # {'name': 'come', 'hobby': [1, 2, 3], 'age': 18}# 2、拆包创立字典dic2 = dict((('name', 'come'), ('age', 18))) # {'name': 'come', 'age': 18}# 3、传入键值创立dic3 = dict(name="come", age=18) # {'name': 'come', 'age': 18}2、增1、罕用 有则批改,无则增加。 dic = {'name': 'come'}# 1、罕用 有则批改,无则增加dic['age'] = 18 # {'name': 'come', 'age': 18}dic['name'] = 'on' # {'name': 'on', 'age': 18}2、setdefault 有则不变,无则增加。 ...

April 5, 2021 · 2 min · jiezi

关于pytorch:pytorch列优先fortranlikereshape的实现与性能

背景numpy 中的reshape函数蕴含一个order变量,默认order='C',即在变形中以后面的维度(行)为优先程序重新排列元素,而order='F'时以前面的维度(列)为优先程序重新排列元素,官网文档中给出了示例: >>> np.reshape(a, (2, 3)) # C-like index orderingarray([[0, 1, 2], [3, 4, 5]])>>> np.reshape(np.ravel(a), (2, 3)) # equivalent to C ravel then C reshapearray([[0, 1, 2], [3, 4, 5]])>>> np.reshape(a, (2, 3), order='F') # Fortran-like index orderingarray([[0, 4, 3], [2, 1, 5]])>>> np.reshape(np.ravel(a, order='F'), (2, 3), order='F')array([[0, 4, 3], [2, 1, 5]])pytorch解决方案在pytorch中,torch.reshape()函数只承受矩阵和形态两个参数,采纳了行优先(C-Style)的变换形式,如果须要应用列优先的变换,须要借助permute()函数,stackoverflow上给出了解决方案: def reshape_fortran(x, shape): if len(x.shape) > 0: x = x.permute(*reversed(range(len(x.shape)))) return x.reshape(*reversed(shape)).permute(*reversed(range(len(shape))))性能测试然而下面的作者狐疑permute()函数外部依然会创立张量的正本,影响效率。因而笔者对这种办法做了测试,并与numpy的内置函数做了比照。测试环境为i9-10900X/RTX2080Ti。 测试代码: import numpy as npimport torchimport timedim1 = 40dim2 = 50dim3 = 5def reshape_fortran(x, shape): if len(x.shape) > 0: x = x.permute(*reversed(range(len(x.shape)))) return x.reshape(*reversed(shape)).permute(*reversed(range(len(shape))))torch.cuda.set_device(0)device = torch.device('cuda')x = [torch.from_numpy(np.random.rand(dim1, dim2)).to(device) for _ in range(100)]xx = [torch.from_numpy(np.random.rand(dim1, dim2)).to(device) for _ in range(100)]for i in range(100): y = x[i].reshape([dim2, dim1])# c reshapet0 = time.time()for i in range(100): y = xx[i].reshape([dim2, dim3, -1])t1 = time.time()# fortran reshapefor i in range(100): yy = reshape_fortran(xx[i], [dim2, dim3, -1])t2 = time.time()print(f'torch build-in reshape: {(t1 - t0)/100} s')print(f'torch permute reshape: {(t2 - t1)/100} s')x = [np.random.rand(dim1, dim2) for _ in range(100)]xx = [np.random.rand(dim1, dim2) for _ in range(100)]for i in range(100): y = x[i].reshape([dim2, dim3, -1])t0 = time.time()for i in range(100): yy = xx[i].reshape([dim2, dim3, -1])t1 = time.time()for i in range(100): yyy = xx[i].reshape([dim2, dim3, -1], order='F')t2 = time.time()print(f'numpy C reshape: {(t1 - t0)/100} s')print(f'numpy F reshape: {(t2 - t1)/100} s')测试后果: ...

March 26, 2021 · 2 min · jiezi

关于python3.x:活动链接再也不用转发朋友圈集赞了python刷赞

你有没有让人帮忙点过赞呢咱们的微信朋友圈,可能会常常遇到有敌人转发链接让进入帮忙点赞的,有的须要微信登陆点赞,有的间接无需登录即可点赞,有的流动链接可能还只限在微信内关上等等,相似这种集赞的流动,其实咱们都是能够刷的,不用费半天劲每天各种转发朋友圈和微信群求赞了,轻轻松松能够搞定。 刷赞思路流动必定都是以网页的模式去分享转发的,那么咱们就能够拿到流动地址,以及通过fildder工具抓取点赞的相干接口,而后通过代理IP申请点赞接口即可,具体的还得看流动的接口规定,大略稍加调整即可。 运行环境Python运行环境:Windows + python3.8 用到的模块:requests、bs4、time、multiprocessing 如未装置的模块,请应用pip instatll xxxxxx进行装置,例如:pip install requests 抓取通过电脑端在fillder工具上抓取到点赞接口,而后拿到接口地址、申请参数以及一些header头信息,上面是我抓取的一个流动的点赞接口相干信息(为了隐衷信息,地址和参数信息都是虚伪的,大家次要看这个思路就能够了) def __init__(self): # 继承Process类 super(XiaoHuanProcess, self).__init__() # 点赞接口地址 self.api_url = 'http://www.xxxxxx.com/topfirst.php?g=Wap&m=Vote&a=ticket' # 点赞申请参数 self.post_param = {'zid': '111', 'vid': '111', 'token': '111'} # 接口申请头信息 self.header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36 QBCore/4.0.1320.400 QQBrowser/9.0.2524.400 Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2875.116 Safari/537.36 NetType/WIFI MicroMessenger/7.0.20.1781(0x6700143B) WindowsWechat(0x63010200)', 'Content-Type': 'application/x-www-form-urlencoded' } # 代理IP地址 self.proxies = {} # 超时工夫 self.time_out = 20抓取代理IP因为总是用同一个用户去申请,必定是不行的,所以,咱们就得须要用代理IP去申请,那么就得抓取网上一些可用的IP地址,这里,我轻易例举一个代理网站(https://ip.jiangxianli.com),因为我测试过,这个网站的IP有效性比拟高,而且IP地址更新也比拟快,具体抓取代码如下: ...

March 26, 2021 · 3 min · jiezi

关于python3.x:翻译实用的Python编程0501Dictsrevisited

目录 | 上一节 (4.4 异样) | [下一节 (5.2 封装)]() 5.1 再谈字典Python 对象零碎次要基于字典实现。本节将对此进行探讨。 字典字典是命名值(named values)的汇合。 stock = { 'name' : 'GOOG', 'shares' : 100, 'price' : 490.1}尽管字典罕用于简略的数据结构,然而字典也用于解释器的要害局部。字典可能是 Python 中最重要的数据类型。 字典和模块在模块内,字典存储所有的全局变量和函数。 # foo.pyx = 42def bar(): ...def spam(): ...能够通过 foo.__dict__ 或 globals() 查看该字典。 { 'x' : 42, 'bar' : <function bar>, 'spam' : <function spam>}字典和对象用户定义对象的时候也应用到了实例字典和类字典。事实上,整个对象零碎次要是基于字典实现的。 字典存储实例数据,如 __dict__: >>> s = Stock('GOOG', 100, 490.1)>>> s.__dict__{'name' : 'GOOG', 'shares' : 100, 'price': 490.1 }当给 self 赋值的时候,你将填充该字典(和实例)。 ...

March 12, 2021 · 4 min · jiezi

关于python3.x:python-cv2去水印

原理是:用2张图片进行比照须要留神 我这个ddd.jpg是本人非专业P的图,失常应该是都是黑的背景而后logo和原图一样大小,2张图片须要一样的像素长宽 import cv2'''两个图片比照去水印'''def get_water(): # 黑底白字 src = cv2.imread('yuan111.jpg') # 默认的黑白图(IMREAD_COLOR)形式读入原始图像 # black.jpg mask = cv2.imread('ddd.jpg', cv2.IMREAD_GRAYSCALE) # 灰度图(IMREAD_GRAYSCALE)形式读入水印蒙幅员像 # 参数:指标修复图像; 蒙幅员(定位修复区域); 选取邻域半径; 修复算法(包含INPAINT_TELEA/INPAINT_NS, 前者算法成果较好) dst = cv2.inpaint(src, mask, 3, cv2.INPAINT_NS) cv2.imwrite('result111.jpg', dst)get_water()

March 11, 2021 · 1 min · jiezi

关于python3.x:翻译实用的Python编程0300Overview

目录 | [上一节 (2 解决数据)]() | [下一节 (4 类和对象)]() 3. 程序组织到目前为止,咱们曾经学习了一些 Python 基础知识并编写了一些简短的脚本。然而,当开始编写更大的程序时,咱们会想要有条理地组织这些程序。本节将深刻探讨对于函数编写,错误处理以及模块的更多细节。最初,您应该可能编写跨多个文件的,并细分为函数的程序。咱们还将提供一些有用的代码模板,以编写更有用的脚本。 [3.1 函数和脚本编写]()[3.2 对于函数的更多细节]()[3.3 异样解决]()[3.4 模块]()[3.5 主模块]()[3.6 对于拥抱灵活性的设计探讨]()目录 | [上一节 (2 解决数据)]() | [下一节 (4 类和对象)]() 注:残缺翻译见 https://github.com/codists/practical-python-zh

February 27, 2021 · 1 min · jiezi

关于python3.x:翻译实用的-Python-编程0207Objects

目录 | 上一节 (2.6 列表推导式) | [下一节 (3 程序组织)]() 2.7 对象本节介绍无关 Python 外部对象模型的更多详细信息,并探讨一些与内存治理,拷贝和类型查看无关的问题。 赋值Python 中的许多操作都与赋值或者存储值无关。 a = value # Assignment to a variables[n] = value # Assignment to a lists.append(value) # Appending to a listd['key'] = value # Adding to a dictionary正告:赋值操作永远不是值拷贝。所有的赋值操作都是援用拷贝(如果你乐意,也能够说是指针拷贝) 赋值示例思考该代码片段: a = [1,2,3]b = ac = [a,b]以下是底层内存操作图。在此示例中,只有一个列表对象 [1,2,3],然而有四个不同的援用指向它。这意味着批改一个值会影响所有的援用。 >>> a.append(999)>>> a[1,2,3,999]>>> b[1,2,3,999]>>> c[[1,2,3,999], [1,2,3,999]]>>>请留神,原始列表中的更改是如何在其它中央显示的。这是因为从未进行任何拷贝,所有的货色都指向同一个货色。 从新赋值从新赋值永远不会重写之前的值所应用的内存。 a = [1,2,3]b = aa = [4,5,6]print(a) # [4, 5, 6]print(b) # [1, 2, 3] Holds the original value切记:变量是名称,不是内存地址 ...

February 26, 2021 · 3 min · jiezi

关于python3.x:IPython-的编程技巧Python-开发必备神器

1,IPython 简介它是一个弱小的 Python 解释器,相比原生的解释器不仅编码好看、且功能强大,特地是在科学计算方面备受推崇。 2,应用 IPython 编程有着怎么的劣势?(1)反对应用 tab 主动补全,并且能够将操作历史记录间接保留至文件。(2)IPython 提供了很多的 magic 函数,能够疾速的实现一些操作。比方:%run、%edit、%save,还有之前文章中提到的 %time、%timeit 等等都对立称之为 magic 函数也就是魔术函数。 %run D:/test.py -- 应用 %run 执行一个 python 文件%hist -- 查看历史输出(3)为应用更加便捷它提供了很多的快捷键。(4)相比默认的 Python 解释器,IPython 编码更加好看更加受到开发者的喜爱。(5)作为交互式编码的代表,IPython 给开发者带来了更加弱小的交互体验。 3,IPython 都有都有哪些快捷键能够应用?更多内容,请返回公众号《老王说编程》查看。 4,魔术命令的应用技巧更多内容,请返回公众号《老王说编程》查看。

February 26, 2021 · 1 min · jiezi

关于python3.x:获取某网页基金净值

import requestsimport timeimport execjsimport matplotlib.pyplot as pltdef getUrl(fscode): head = 'http://fund.eastmoney.com/pingzhongdata/' tail = '.js?v='+ time.strftime("%Y%m%d%H%M%S",time.localtime()) return head+fscode+tail#获取净值def getWorth(fscode): #用requests获取到对应的文件 content = requests.get(getUrl(fscode)) #应用execjs获取到相应的数据 jsContent = execjs.compile(content.text) name = jsContent.eval('fS_name') code = jsContent.eval('fS_code') #单位净值走势 netWorthTrend = jsContent.eval('Data_netWorthTrend') #累计净值走势 ACWorthTrend = jsContent.eval('Data_ACWorthTrend') netWorth = [] ACWorth = [] #提取出外面的净值 for dayWorth in netWorthTrend[::-1]: netWorth.append(dayWorth['y']) for dayACWorth in ACWorthTrend[::-1]: ACWorth.append(dayACWorth[1]) print(name,code) return netWorth, ACWorthnetWorth, ACWorth = getWorth('003511')print(netWorth)plt.figure(figsize=(10,5))plt.plot(netWorth[:60][::-1])plt.show()

January 24, 2021 · 1 min · jiezi

关于python3.x:pyinstaller-带资源打包exe

1.代码增加 # 生成资源文件目录拜访门路def resource_path(self, resource_path): if getattr(sys, 'frozen', False): # 是否Bundle Resource base_path = sys._MEIPASS else: base_path = os.path.abspath(".") return os.path.join(base_path, resource_path)2.调用办法 icon_path = self.resource_path(os.path.join("resource/orange.png"))self.icon = QIcon(icon_path)self.setWindowTitle('单据生成工具')self.setWindowIcon(self.icon)3.执行命令生成.spec文件 pyinstaller -w -F main.py4.批改.spec文件

January 23, 2021 · 1 min · jiezi

关于python3.x:编写python的daemon程序

以前把守护过程与后台任务搞混了,前面看了文章才晓得这两者的区别,写此文表白本人对守护过程的了解. 1:什么是守护过程?所谓守护过程是一种是 Linux 的一种长期运行的后盾服务过程,httpd、named、sshd 等服务都是以守护过程 Daemon 形式运行的,通常服务名称以字母d结尾,也就是 Daemon 第一个字母. 无需管制终端(不须要与用户交互)在后盾运行生命周期比拟长,个别是随系统启动和敞开2:守护过程必要性通常咱们执行工作时是在前台执行,霸占了以后终端,此时无奈进行操作,就算咱们增加了 &符号,将程序放到后盾,但也就因为终端断网等问题,导致程序中断。 所要晓得的是:在目前的linux上,有了systemd这个服务,这个服务管理工具能够不便咱们写在后盾运行的程序,甚至能够代替这种守护过程。通过把写服务的配置文件,让systemd监控咱们的程序,能够随系统启动而运行,能够设定启动条件,及其的不便。 3:过程组$ ps -o pid,pgid,ppid,comm | cat PID PGID PPID COMMAND10179 10179 10177 bash10263 10263 10179 ps10264 10263 10179 catbash:过程和过程组ID都是 10179,父过程其实是 sshd(10177)ps:过程和过程组ID都是 10263,父过程是 bash(10179),因为是在 Shell 上执行的命令cat:过程组 ID 与 ps 的过程组 ID 雷同,父过程同样是 bash(10179)4:会话组 多个过程形成一个过程组,而会话组是由多个过程组构建而。而过程组又被称为job,会话有前台作业,也会有后台作业;一个会话能够有一个管制终端,当管制终端有输出和输入时都会传递给前台过程组,比方Ctrl + Z。会话的意义在于能将多个作业通过一个终端管制,一个前台操作,其它后盾运行。 那么如何编写守护过程呢?其实编写守护过程很简略,只须要遵循一下几点即可 1:创立子过程,父过程退出PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 0 49 49 49 pts/2 70 Ss 0 0:00 /bin/bash 49 70 70 49 pts/2 70 R+ 0 0:00 \_ ps axjf 0 17 17 17 pts/1 68 Ss 0 0:00 /bin/bash 17 68 68 17 pts/1 68 S+ 0 0:00 \_ python hello.py 68 69 68 17 pts/1 68 S+ 0 0:00 \_ python hello.py 0 1 1 1 pts/0 1 Ss+ 0 0:00 /bin/bash过程 fork 后,父过程退出。这么做的起因有 2 点: ...

January 6, 2021 · 2 min · jiezi

关于python3.x:python小技巧1

在浏览《晦涩的python》以及《深刻了解python个性》时发现这两本书都提及了python的一个库:collection.namedtuple,这个库能够疾速的创立一个tuple对象并且能够为其命令,而且输入查看该对象值时,tuple中是以key=value的模式存储,不便了用户的应用,最次要的是:这个对象在内存中所耗费的字节数与一般tuple一样! >>> from collections import namedtuple>>> Card = namedtuple('Card',"rank suit")>>> Card<class '__main__.Card'>>>> type(Card)<class 'type'>>>> ranks = [str(n) for n in range(2,11)] +list("JQKA")>>> suits = 'spades diamonds clubs hearts'>>> cards = [Card(rank,suit) for rank in ranks for suit in suits]>>> cards[Card(rank='2', suit='s'), Card(rank='2', suit='p'), Card(rank='2', suit='a'), Card(rank='2', suit='d'), Card(rank='2', suit='e'), Card(rank='2', suit='s'), Card(rank='2', suit=' ') 前面省略能够发现应用了namedtupe后,每个tuple有了名称,而且存储格局为key=value的模式。 同时疾速创立牌组的列表的推到式应用于笛卡尔积这样的模式,疾速的构建list,无论是一个变量,还是变量; 对于tuple 都晓得tuple中存储的是不能轻易批改的变量值,那么上面这段代码批改后会发现什么状况呢? >>> t = (1,2,[30,40])>>> t[2][30, 40]>>> t[2]+=[50,60]状况1:因为tuple存储的是不可批改的变量,批改会产生谬误; 状况2:因为list是可变对象,能够批改胜利;而且没有什么谬误提醒; 惋惜的是,批改后既提醒了谬误,也让用户批改了其中可变对象的值 >>> t = (1,2,[30,40])>>> t[2][30, 40]>>> t[2]+=[50,60]Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: 'tuple' object does not support item assignment>>> t(1, 2, [30, 40, 50, 60])对于list ...

December 26, 2020 · 2 min · jiezi

关于python3.x:unicodedata-Unicode-数据库

此模块提供了对 Unicode Character Database (UCD) 的拜访。UCD 中定义了所有 unicode 字符的字符属性。 前情提醒: 测试代码中,右尖括号(>)表示命令行中输出的命令; 独自一行并以井字符(#)结尾的为输入构造; 库的导入仅在本文的第一个测试代码中展示,其余代码块均省略库的导入代码。 零碎类型: Windows 10python 版本: Python 3.9.0unicodedata.lookup(name)通过 unicode 字符的名称来查找 unicode 字符。 参数: name: unicode 字符的名称返回值: str,unicode 字符依据传入的名称,来查找对应的 unicode 字符,如果查找到则返回 unicode 字符,否则会引发 KeyError 谬误。 import unicodedataprint(unicodedata.lookup('Cjk Compatibility Ideograph-2f80f'))# ????print(unicodedata.lookup('Armenian Small Ligature Men Now'))# ﬓprint(unicodedata.lookup('111'))# Traceback (most recent call last):# File "e:\project\test\test.py", line 3, in <module># print(unicodedata.lookup('111'))# KeyError: "undefined character name '111'"unicodedata.name(chr[, default])获取 unicode 字符的名称。 参数: chr: str,字符 default: str,可选参数,当没有查找到 unicode 字符的名称时的默认返回值返回值: str,unicode 字符的名称或传入的默认值依据传入的 unicode 字符,来查找对应的名称,如果查找到则返回名称,如果未查找到并且传入了默认值则返回默认值,如果未查找到并且没有传入默认值则会引发 ValueError 谬误。 ...

December 23, 2020 · 2 min · jiezi

关于python3.x:python装饰器学习详解函数部分

最近浏览《晦涩的python》看见其用函数写装璜器局部写的很好,想写一些本人的读书笔记。家喻户晓,装璜器是python学习过程中的一道门槛,初学者学习时往往是知其然,不知其所以然,这样的后果是导致一段时间后会忘记掉该局部内容,只好再次去学习,拉高了学习老本。 想学好python的装璜器,须要明确一下几点; 1:闭包1)函数嵌套2)外部函数应用内部函数的变量3)内部函数的返回值为外部函数 接下来看看《晦涩的python》中的例子,我略微批改了一下: >>> def make_averager(series=[]):... def averager(new_value):... series.append(new_value)... total = sum(series)... return total/len(series)... return averager...>>> avg = make_averager()>>> avg<function make_averager.<locals>.averager at 0x10b82cb00>>>> avg(10)10.0>>> avg(11)10.5>>> avg(12)11.0 函数 make_averager 实现了一个 计算以后所有数字的平均值的性能,一直的增加一个值,而后计算以后的平均值。 avg这个对象内存地址指向了make_averager这个函数的外部函数中,而且avg通过一直的增加值进行平均值计算,按理说在这个外部函数没有存储new_value的空间,而且在make_averager对avg赋值后,函数返回后series这个变量也应该隐没了,然而avg却仍然能够进行计算。 这就是闭包,外部函数averager应用里面的自在变量,也就是属于make_averager的局部变量series >>> avg.__code__.co_varnames('new_value', 'total')>>> avg.__code__.co_freevars('series',) 能够发现avg的自在变量是make_averager的局部变量,就是说闭包里的外部函数能够应用内部函数的变量,即咱们下面提到的第二点:“外部函数应用内部函数的变量”,注:自在变量只能read,并不能write,不然会提醒本地变量并没有赋值的谬误,咱们举的例子没遇到这个问题,因为咱们没有给 series 赋值,咱们只是调 用 series.append,并把它传给 sum 和 len。也就是说,咱们利用了 列表是可变的对象这一事实。下图是书中提供的闭包范围图: 2:装璜器的实现所谓装璜器,就是在不扭转根底函数的性能上再次给它封装一层,达到咱们想要的目标,接下来我举个简略的例子: deco_demo.py 1 def col(func): 2 def inner(*args, **kwargs): 3 print(func.__name__) 4 print(locals()) 5 print(inner.__code__.co_varnames) 6 print(inner.__code__.co_freevars) 7 return func(*args, **kwargs) 8 return inner 9 10 11 @col 12 def new_add(x): 13 return x+2 14 15 16 def new_add_1(x): 17 return x+3 18 19 20 print(new_add(3)) 21 22 new_add_1 = col(new_add_1) 23 print(new_add_1(3))下方是它的返回后果: ...

December 20, 2020 · 3 min · jiezi

关于python3.x:pythontesseract-实现文字识别

Tesseract装置参考上一篇文章https://segmentfault.com/a/11... pytesseract装置sudo pip3 install pytesseract下载中文训练包https://github.com/tesseract-...将下载的训练包chi-sim.trainedata放入到tessdata下,其中源码装置的地位在: cd /usr/local/share/tessdata示例import pytesseractfrom PIL import Imageim = Image.open("demo.png")string = pytesseract.image_to_string(im, lang='langyp')print(string)

December 18, 2020 · 1 min · jiezi

关于python3.x:如何快速上手项目

对于团队的新成员来讲,最难的事件之一就是了解“全局观”——类之间如何交互,数据如何在整个零碎中流动,以及入口点在哪里。设计零碎的人常常遗记给这些货色加正文,“只缘身在此山中”。

December 4, 2020 · 1 min · jiezi

关于python3.x:python学习函数

函数的特点是用def进行定义,定义实现后用:进行完结函数体通过缩进辨认,定义完函数回车确认后,主动的换行缩进,函数体内嵌套函数体的邀留神缩进。函数中的变量分为全局变量和局部变量,全局变量在程序里均可拜访,但不能在函数中从新定义,定义后就变为全新的只是名字雷同的局部变量。如果肯定要进行批改能够通过global关键字进行润饰内嵌函数是函数体内存在函数,外部函数只能通过调用内部函数能力调用外部函数。一种非凡的内嵌函数叫闭包,内嵌函数调用内部函数的参数。lambda表达式,是一种简便的函数表达形式。次要的特点:① 用作脚本是能省下定义函数过程。② 防止函数名反复 ③ 能简化代码可读性例如: a = lambda x: 2*x+1print(a(5))最初的输入后果为 在罕用的filter和map中罕用到lambda表达式。如filter函数定义为filter(①function or none,②iterable)当参数①为函数时,参数②中的值将作为参数进行传递,此时参数①能够应用lambda表达式。如通过fileter求出10以内的奇数: show = filter(lambda x: x%2,range(10))print(list(show))最初后果为:

November 30, 2020 · 1 min · jiezi

关于python3.x:fastapi-框架-实现接口与zabbix自定义监控

前情与试验目标 背景:服务器早晨负载常常忽然暴涨,只有node服务,然而双机另一台无问题解决办法: 通过python fastapi实现load,pm2信息,cup等接口,自定义zabbix脚本监控报警 实现 astapi实现load,pm2信息,cup等接口#!/usr/bin/python# -*- coding:utf-8 -*-import subprocessimport urllib.requestfrom fastapi import FastAPIimport platformimport socket,requestsfrom ansible2 import *import ansible_runnerimport os, sys, json, datetime, timeimport urllib.requestfrom fastapi.responses import HTMLResponsefrom fastapi import FastAPIfrom starlette.requests import Requestfrom starlette.responses import Responsefrom fastapi import FastAPI, Formfrom fastapi import Cookiefrom starlette.templating import Jinja2Templatesfrom starlette.staticfiles import StaticFilesfrom utils import sqlhelperimport pymysqldef ansible_linux_command(hosts1,cmd1):    ansible3 = MyAnsiable2(inventory='/data/ansible/host/hosts', connection='smart')    ansible3.run(hosts=hosts1, module="shell", args=cmd1)    stdout_dict = json.loads(ansible3.get_result())    print(stdout_dict, type(stdout_dict))    print(stdout_dict['success'][hosts1]['stdout'])    source_list = stdout_dict['success'][hosts1]['stdout'].split("\n")    return source_list[0]def ansible_load(hosts1):    pid_listf = float(ansible_linux_command(hosts1, "uptime | awk {tprint} |tr -d ','".format(tprint="'{print $11}'")))    print(pid_listf,type(pid_listf))    if pid_listf > 10.00:        stdout_list2 = {"load": ansible_linux_command(hosts1, "uptime | awk {tprint} |tr -d ','".format(tprint="'{print $11}'")),"pm2": ansible_linux_command(hosts1, 'pm2 ls|tr "\n" " "'),"cpu": ansible_linux_command(hosts1, 'ps aux|grep -v PID|sort -rn -k +3|head|tr "\n" " "')}    else:        stdout_list2 = {"load": ansible_linux_command(hosts1, "uptime | awk {tprint} |tr -d ','".format(tprint="'{print $11}'"))}        return stdout_list2@app.get("/load/{hosts1}")def read_load(hosts1: str):    print(hosts1, '#######################hosts')    print(ansible_load(hosts1))    return ansible_load(hosts1)if __name__ == '__main__':    import uvicorn    uvicorn.run(app=app,                host="192.168.0.215",                port=9999,                workers=1)ansible 模块[root@dev-technology-215l fastapi_websocket_logs]# cat ansible2.py import jsonimport shutilfrom ansible.module_utils.common.collections import ImmutableDictfrom ansible.parsing.dataloader import DataLoaderfrom ansible.vars.manager import VariableManagerfrom ansible.inventory.manager import InventoryManagerfrom ansible.playbook.play import Playfrom ansible.executor.task_queue_manager import TaskQueueManagerfrom ansible.plugins.callback import CallbackBasefrom ansible import contextimport ansible.constants as Cclass ResultCallback(CallbackBase):    """    重写callbackBase类的局部办法    """    def __init__(self, *args, **kwargs):        super().__init__(*args, **kwargs)        self.host_ok = {}        self.host_unreachable = {}        self.host_failed = {}        self.task_ok = {}    def v2_runner_on_unreachable(self, result):        self.host_unreachable[result._host.get_name()] = result    def v2_runner_on_ok(self, result, **kwargs):        self.host_ok[result._host.get_name()] = result    def v2_runner_on_failed(self, result, **kwargs):        self.host_failed[result._host.get_name()] = resultclass MyAnsiable2():    def __init__(self,        connection='local',  # 连贯形式 local 本地形式,smart ssh形式        remote_user=None,    # ssh 用户        remote_password=None,  # ssh 用户的明码,应该是一个字典, key 必须是 conn_pass        private_key_file=None,  # 指定自定义的私钥地址        sudo=None, sudo_user=None, ask_sudo_pass=None,        module_path=None,    # 模块门路,能够指定一个自定义模块的门路        become=None,         # 是否提权        become_method=None,  # 提权形式 默认 sudo 能够是 su        become_user=None,  # 提权后,要成为的用户,并非登录用户        check=False, diff=False,        listhosts=None, listtasks=None,listtags=None,        verbosity=3,        syntax=None,        start_at_task=None,        inventory=None):        # 函数文档正文        """        初始化函数,定义的默认的选项值,        在初始化的时候能够传参,以便笼罩默认选项的值        """        context.CLIARGS = ImmutableDict(            connection=connection,            remote_user=remote_user,            private_key_file=private_key_file,            sudo=sudo,            sudo_user=sudo_user,            ask_sudo_pass=ask_sudo_pass,            module_path=module_path,            become=become,            become_method=become_method,            become_user=become_user,            verbosity=verbosity,            listhosts=listhosts,            listtasks=listtasks,            listtags=listtags,            syntax=syntax,            start_at_task=start_at_task,        )        # 三元表达式,如果没有传递 inventory, 就应用 "localhost,"        # 指定 inventory 文件        # inventory 的值能够是一个 资产清单文件        # 也能够是一个蕴含主机的元组,这个仅仅实用于测试        #  比方 : 1.1.1.1,    # 如果只有一个 IP 最初必须有英文的逗号        #  或者: 1.1.1.1, 2.2.2.2        self.inventory = inventory if inventory else "localhost,"        # 实例化数据解析器        self.loader = DataLoader()        # 实例化 资产配置对象        self.inv_obj = InventoryManager(loader=self.loader, sources=self.inventory)        # 设置明码        self.passwords = remote_password        # 实例化回调插件对象        self.results_callback = ResultCallback()        # 变量管理器        self.variable_manager = VariableManager(self.loader, self.inv_obj)    def run(self, hosts='localhost', gether_facts="no", module="ping", args='', task_time=0):        """        参数阐明:        task_time -- 执行异步工作时期待的秒数,这个须要大于 0 ,等于 0 的时候不反对异步(默认值)。这个值应该等于执行工作理论耗时工夫为好        """        play_source =  dict(            name = "Ad-hoc",            hosts = hosts,            gather_facts = gether_facts,            tasks = [                # 这里每个 task 就是这个列表中的一个元素,格局是嵌套的字典                # 也能够作为参数传递过去,这里就简单化了。               {"action":{"module": module, "args": args}, "async": task_time, "poll": 0}])        play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader)        tqm = None        try:            tqm = TaskQueueManager(                      inventory=self.inv_obj ,                      variable_manager=self.variable_manager,                      loader=self.loader,                      passwords=self.passwords,                      stdout_callback=self.results_callback)            result = tqm.run(play)        finally:            if tqm is not None:                tqm.cleanup()            shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)    def playbook(self,playbooks):        """        Keyword arguments:        playbooks --  须要是一个列表类型        """        from ansible.executor.playbook_executor import PlaybookExecutor        playbook = PlaybookExecutor(playbooks=playbooks,                        inventory=self.inv_obj,                        variable_manager=self.variable_manager,                        loader=self.loader,                        passwords=self.passwords)        # 应用回调函数        playbook._tqm._stdout_callback = self.results_callback        result = playbook.run()    def get_result(self):      result_raw = {'success':{},'failed':{},'unreachable':{}}      # print(self.results_callback.host_ok)      for host,result in self.results_callback.host_ok.items():          result_raw['success'][host] = result._result      for host,result in self.results_callback.host_failed.items():          result_raw['failed'][host] = result._result      for host,result in self.results_callback.host_unreachable.items():          result_raw['unreachable'][host] = result._result      # 最终打印后果,并且应用 JSON 持续格式化      print(json.dumps(result_raw, indent=4))            return json.dumps(result_raw)测试[root@dev-technology-215l fastapi_websocket_logs]# curl -s http://192.168.0.215:9999/load/172.16.19.43{"load":"9.57"}[root@dev-technology-215l fastapi_websocket_logs]# pwd/data/shell/fastapi_websocket_logszabbix自定义监控脚本编写load_monitor.py [root@sit-cdpapp-162l zabbix]# cat load_monitor.py #!/usr/bin/python# -*- coding:utf-8 -*-import subprocessimport os,sys,json,datetime,timeimport localeimport reimport requestshost2 = sys.argv[1]r = requests.get('http://192.168.0.215:9999/load/{thost}'.format(thost=host2), timeout=10)print(r.text)批改 /etc/zabbix/zabbix_agentd.conf 文件[root@sit-cdpapp-162l zabbix]# grep  -v  "#"  /etc/zabbix/zabbix_agentd.confPidFile=/var/run/zabbix/zabbix_agentd.pidLogFile=/var/log/zabbix/zabbix_agentd.logLogFileSize=0Server=192.168.0.12ServerActive=192.168.0.12Hostname=sit-spring-app162Timeout=10Include=/etc/zabbix/zabbix_agentd.d/UnsafeUserParameters=1UserParameter=process.all[*],/etc/zabbix/processstatus.sh $1 $2UserParameter=java_monitor[*],/etc/zabbix/java_monitor.py $1UserParameter=cdp-java_monitor[*],/etc/zabbix/cdp-java_monitor.py $1UserParameter=node_monitor[*],/etc/zabbix/node_monitor.py $1 $2UserParameter=load_monitor[*],/etc/zabbix/load_monitor.py $1UserParameter=pro_elk_port[*],/etc/zabbix/elk_socket_port.py $1 $2UserParameter=node_monitor2[*],/etc/zabbix/node_monitor-nodomain.py $1 $2UserParameter=nginx_check_upstream[*],/etc/zabbix/nginx_check_upstream.py $1 $2 ...

November 12, 2020 · 6 min · jiezi

关于python3.x:基于Python3Autosub以及Ffmpeg配合GoogleTranslation为你的影片实现双语版字幕逐字稿

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_169 为影片加字幕其实是一件十分消耗工夫的事件,尤其是对于打字慢的敌人来说。当然不光为影片加字幕,在其余畛域,相似的逐字稿也是工作中防止不了的内容。比方写论文,如果内容中有访谈,就必须要附上逐字稿,又或者是会议的记录等等。本次应用基于Python3的AutoSub库对实时语音进行辨认,而后再通过GoogleTranslation的在线API接口对语音辨认后的内容进行翻译,这样就能够失去一份双语字幕(逐字稿),这里的双语不只针对国语+英语组合,也能够蕴含其余国家,包含小语种地区,十分不便。 首先须要装置ffmpeg,这个软件在之前有过介绍:Python3利用ffmpeg针对视频进行一些操作,Win10用户能够依据这篇文章进行装置,如果是Mac用户则非常简单,应用Homebrew就能够十分不便的进行装置 brew install ffmpeg其后装置autosub,这个库其实就是针对Google的语音辨认封装而成的,最早基于Python2,近几年也呈现很多“魔改版”,这里举荐尽量装置原版的基于Python3的最新版,而应用pip间接install往往无奈装置最新版,所以这里举荐用git版本库地址的形式进行装置,这样能够防止很多坑: pip3 install git+https://github.com/agermanidis/autosub.git装置胜利后,输出命令: autosub -h就能够看到应用阐明: liuyue:myr liuyue$ autosub -h usage: autosub [-h] [-C CONCURRENCY] [-o OUTPUT] [-F FORMAT] [-S SRC_LANGUAGE] [-D DST_LANGUAGE] [-K API_KEY] [--list-formats] [--list-languages] [source_path] positional arguments: source_path Path to the video or audio file to subtitle optional arguments: -h, --help show this help message and exit -C CONCURRENCY, --concurrency CONCURRENCY Number of concurrent API requests to make -o OUTPUT, --output OUTPUT Output path for subtitles (by default, subtitles are saved in the same directory and name as the source path) -F FORMAT, --format FORMAT Destination subtitle format -S SRC_LANGUAGE, --src-language SRC_LANGUAGE Language spoken in source file -D DST_LANGUAGE, --dst-language DST_LANGUAGE Desired language for the subtitles -K API_KEY, --api-key API_KEY The Google Translate API key to be used. (Required for subtitle translation) --list-formats List all available subtitle formats --list-languages List all available source/destination languages ...

September 30, 2020 · 3 min · jiezi

关于python3.x:Python3常用字符串操作

1. str.strip去掉字符串首位指定的字符,默认去掉空白字符intput=" nnn入门小站nnn "print('[%s]' % input)# strip不会扭转原字符串的值,所以须要一个新变量接管newInput=input.strip()print('[%s]' % newInput)# 去掉首位的n字符print('[%s]' % input.strip('n'))# 去掉首位的n字符+空白字符print('[%s]' % input.strip('n').strip())[ 入门小站 ][入门小站][ 入门小站 ][入门小站]2. str.center应用指定字符对字符串进行对齐intput="入门小站"print(input.center(12,'#'))### 入门小站 ###3. str.count()统计字符串再另外一个字符串中呈现的次数# 语法 str.count(value, start, end) # start 起始索引 可选# end 完结索引 可选input="入门 入门小站 入门 rumen 入门"print(input.count('入门'))# 指定查找范畴print(input.count('入门',2,7))414. str.find() 查找字符串首次呈现的地位# 语法 str.find(value,start,end)# start 起始索引 可选# end 完结索引 可选# 如果没有找到则返回-1input="入门 入门小站 入门 rumen 入门"print(input.find('入门'))# 指定范畴print(input.find('入门',2,7))035. str.rfind(value,start,end) 查找字符串最初呈现的地位# 语法 str.rfind(value,start,end)# start 起始索引 可选# end 完结索引 可选# 如果没有找到则返回-1input="入门 入门小站 入门 rumen 入门"print(input.rfind('入门'))# 指定范畴print(input.rfind('入门',2,7))1736. str.swapcase()返回一个字符串的正本,并且对字符串进行大小写转换input=" ru men XIAO zhan "print(input.swapcase()) RU MEN xiao ZHAN 7. str.startswith()判断字符串是不是以某个字符串开始# 语法:str.startswith(prefix[, start[, end]]) -> bool# start 起始索引 可选# end 完结索引 可选# 返回bool值input="入门小站"print(input.startswith('入门'))# 指定范畴print(input.startswith('入门',2))TrueFalse8.str.endswith()判断字符串是不是以某个字符串结尾# str.endswith(suffix[, start[, end]]) -> bool# start 起始索引 可选# end 完结索引 可选# 返回bool值input="入门小站"print(input.endswith('小站'))# 指定范畴print(input.endswith('小站',2))TrueTrue9. str.split() 宰割字符串成一个list,默认宰割符是任意数量的空白字符# 语法:str.split(self, /, sep=None, maxsplit=-1)input=" n 入门 n 小站 n "print(input.split())# 指定宰割字符print(input.split('n'))['n', '入门', 'n', '小站', 'n'][' ', ' 入门 ', ' 小站 ', ' ']10. 字符串大小写转换# 10.1 str.capitalize() 将字符串的第一个字符转成大写input="ru mEn z "print(input.capitalize())# 10.2 str.upper() 将所有字符转换成大写print(input.upper())# 10.3 str.title() 将每个单词的首字符转换成大写,其余字符转换成小写print(input.title())Ru men z RU MEN Z Ru Men Z 11. str.ljust()和str.rjust()字符串首位用指定的字符填充到指定长度,默认以空格填充# 语法: ljust(self, width, fillchar=' ', /)# 语法: rjust(self, width, fillchar=' ', /)# width 为填充后的字符串的长度input="rumenz"print(intput.ljust(20,'#'))print(input.rjust(20,'$'))入门小站################$$$$$$$$$$$$$$rumenz12. str.zfill() 字符串后面填充0# 语法:str.zfill(self, width, /)# width 字符串填充后字符串的长度input="rumenz"print(intput.zfill(20))0000000000000000入门小站13. 定义一个多行字符串input='''入门小站rumenz'''print(input)入门小站rumenz ...

September 16, 2020 · 2 min · jiezi

关于python3.x:Python-abc抽象基类

该模块提供了在Python中定义形象基类(ABC - Abstract Base Class)的根底构造,参考PEP 3119;至于为何将其增加到Python,也能够看看PEP 3141和numbers模块无关基于ABC的数字的类层次结构的模块。 容器collections模块具备一些衍生自ABC的具体类。当然,这些能够进一步继承衍生。此外, collections.abc子模块具备一些ABC,可用于测试:类或实例是否提供特定的接口,例如,是否可哈希或是否为映射。 此模块提供ABCMeta用于定义ABC 的元类和帮忙程序类,ABC以通过继承来代替地定义ABC: classabc.`ABC 具备ABCMeta作为其元类的帮忙程序类。应用此类,能够通过ABC 防止有时混同元数据用法的简略派生来创立形象基类,例如: from abc import ABCclass MyABC(ABC): pass请留神,类型ABC为still ABCMeta,因而从继承继承ABC须要无关元类应用的惯例预防措施,因为多重继承可能会导致元类抵触。也能够通过传递 metaclass 关键字并ABCMeta间接应用来定义形象基类,例如: from abc import ABCMetaclass MyABC(metaclass=ABCMeta): pass3.4版的新性能。 class abc.`ABCMeta`用于定义形象基类(ABC)的元类。 应用此元类创立一个ABC。ABC能够间接子类化,而后充当混合类。您还能够将不相干的具体类(甚至是内置类)和不相干的ABC注册为“虚构子类” –内置issubclass()函数会将它们及其后辈视为注册ABC的子类,然而注册ABC不会显示在其MRO(办法解决程序)中,由注册ABC定义的办法实现也将不可调用(甚至不能通过调用 super())。1个 应用元类创立的类ABCMeta具备以下办法: register(_subclass_) 将__subclass__注册为该ABC的“虚构子类”。例如: from abc import ABCclass MyABC(ABC): passMyABC.register(tuple)assert issubclass(tuple, MyABC)assert isinstance((), MyABC)在版本3.3中更改:返回注册的子类,以容许用作类装璜器。 在版本3.4中更改:要检测对的调用register(),能够应用该 get_cache_token()性能。 您还能够在形象基类中重写此办法: __subclasshook__(_子类_) (必须定义为类办法。) 查看_子类_是否被视为此ABC的子类。这意味着您能够自定义issubclass进一步的行为,而无需调用register()要思考为ABC的子类的每个类。(此类办法是从__subclasscheck__()ABC 的办法中调用的。) 这个办法应该返回True,False或NotImplemented。如果返回True,则将该_子类_视为此ABC的子类。如果返回False,则即便该子类通常是一个_子类,_也不会将该_子类_视为该ABC的子类。如果返回 NotImplemented,则应用惯例机制持续子类查看。 为了演示这些概念,请看以下示例ABC定义: class Foo: def __getitem__(self, index): ... def __len__(self): ... def get_iterator(self): return iter(self)class MyIterable(ABC): @abstractmethod def __iter__(self): while False: yield None def get_iterator(self): return self.__iter__() @classmethod def __subclasshook__(cls, C): if cls is MyIterable: if any("__iter__" in B.__dict__ for B in C.__mro__): return True return NotImplementedMyIterable.register(Foo)ABC MyIterable将规范可迭代办法定义 __iter__()为形象办法。此处给出的实现仍能够从子类中调用。该get_iterator()办法也是MyIterable形象基类的一部分,然而在非形象派生类中不用重写此办法~~~~。 ...

August 25, 2020 · 2 min · jiezi