• [技术干货] 最全的 pip 使用指南,50 % 你可能都没用过~
    所有的 Python 开发者都清楚,Python 之所以如此受欢迎,能够在众多高级语言中,脱颖而出,除了语法简单,上手容易之外,更多还要归功于 Python 生态的完备,有数以万计的 Python 爱好者愿意以 Python 为基础封装出各种有利于开发的第三方工具包。这才使用我们能够以最快的速度开发出一个满足基本需要的项目,而不是每次都重复造轮子。Python 从1991年诞生到现在,已经过去28个年头了,这其间产生了数以万计的第三方包,且每个包都会不断更新,会有越来越多的版本。当你在一个复杂的项目环境中,如果没有一个有效的依赖包管理方案,项目的维护将会是一个大问题。pip 是官方推荐的包管理工具,在大多数开发者眼里,pip 几乎是 Python 的标配。当然也有其他的包管理工具distutils:仅用于打包和安装,严格来讲不算是包管理工具setuptools:distutils的增强版,扩展了distutils,提供更多的功能,引入包依赖的管理,easy_install就是它的一个命令行工具,引入了 egg 的文件格式。Pipenv:一个集依赖包管理(pip)及虚拟环境管理(virtualenv)的工具还有其他的,这里不一一列出。今天的主角是 pip ,大家肯定不会陌生。但我相信不少人,只是熟悉几个常用的用法,而对于其他几个低频且实用的用法,却知之甚少,这两天,我查阅官方文档,把这些用法整理了一下,应该是网络上比较全的介绍。1. 查询软件包查询当前环境安装的所有软件包$ pip list查询 pypi 上含有某名字的包$ pip search pkg查询当前环境中可升级的包$ pip list --outdated查询一个包的详细内容$ pip show pkg2. 下载软件包在不安装软件包的情况下下载软件包到本地$ pip download --destination-directory /local/wheels -r requirements.txt下载完,总归是要安装的,可以指定这个目录中安装软件包,而不从 pypi 上安装。$ pip install --no-index --find-links=/local/wheels -r requirements.txt当然你也从你下载的包中,自己构建生成 wheel 文件$ pip install wheel $ pip wheel --wheel-dir=/local/wheels -r requirements.txt3. 安装软件包使用 pip install <pkg> 可以很方便地从 pypi 上搜索下载并安装 python 包。如下所示$ pip install requests这是安装包的基本格式,我们也可以为其添加更多参数来实现不同的效果。3.1 只从本地安装,而不从 pypi 安装# 前提你得保证你已经下载 pkg 包到 /local/wheels 目录下 $ pip install --no-index --find-links=/local/wheels pkg3.2 限定版本进行软件包安装以下三种,对单个 python 包的版本进行了约束# 所安装的包的版本为 2.1.2 $ pip install pkg==2.1.2 # 所安装的包必须大于等于 2.1.2 $ pip install pkg>=2.1.2 # 所安装的包必须小于等于 2.1.2 $ pip install pkg<=2.1.2以下命令用于管理/控制整个 python 环境的包版本# 导出依赖包列表 pip freeze >requirements.txt # 从依赖包列表中安装 pip install -r requirements.txt # 确保当前环境软件包的版本(并不确保安装) pip install -c constraints.txt3.3 限制不使用二进制包安装由于默认情况下,wheel 包的平台是运行 pip download 命令 的平台,所以可能出现平台不适配的情况。比如在 MacOS 系统下得到的 pymongo-2.8-cp27-none-macosx_10_10_intel.whl 就不能在 linux_x86_64 安装。使用下面这条命令下载的是 tar.gz 的包,可以直接使用 pip install 安装。比 wheel 包,这种包在安装时会进行编译,所以花费的时间会长一些。# 下载非二进制的包 $ pip download --no-binary=:all: pkg # 安装非二进制的包 $ pip install pkg --no-binary3.4 指定代理服务器安装当你身处在一个内网环境中时,无法直接连接公网。这时候你使用pip install 安装包,就会失败。面对这种情况,可以有两种方法:下载离线包拷贝到内网机器中安装使用代理服务器转发请求第一种方法,虽说可行,但有相当多的弊端步骤繁杂,耗时耗力无法处理包的依赖问题这里重点来介绍,第二种方法:$ pip install --proxy [user:passwd@]http_server_ip:port pkg每次安装包就发输入长长的参数,未免有些麻烦,为此你可以将其写入配置文件中:$HOME/.config/pip/pip.conf对于这个路径,说明几点不同的操作系统,路径各不相同# Linux/Unix: /etc/pip.conf ~/.pip/pip.conf ~/.config/pip/pip.conf # Mac OSX: ~/Library/Application Support/pip/pip.conf ~/.pip/pip.conf /Library/Application Support/pip/pip.conf # Windows: %APPDATA%\pip\pip.ini %HOME%\pip\pip.ini C:\Documents and Settings\All Users\Application Data\PyPA\pip\pip.conf (Windows XP) C:\ProgramData\PyPA\pip\pip.conf (Windows 7及以后)若在你的机子上没有此文件,则自行创建即可如何配置,这边给个样例:[global] index-url = http://mirrors.aliyun.com/pypi/simple/  # 替换出自己的代理地址,格式为[user:passwd@]proxy.server:port proxy=http://xxx.xxx.xxx.xxx:8080  [install] # 信任阿里云的镜像源,否则会有警告 trusted-host=mirrors.aliyun.com3.5 安装用户私有软件包很多人可能还不清楚,python 的安装包是可以用户隔离的。如果你拥有管理员权限,你可以将包安装在全局环境中。在全局环境中的这个包可被该机器上的所有拥有管理员权限的用户使用。如果一台机器上的使用者不只一样,自私地将在全局环境中安装或者升级某个包,是不负责任且危险的做法。面对这种情况,我们就想能否安装单独为我所用的包呢?庆幸的是,还真有。我能想到的有两种方法:使用虚拟环境将包安装在用户的环境中虚拟环境,之前写过几篇文章,这里不再展开讲。今天的重点是第二种方法,教你如何安装用户私有的包?命令也很简单,只要加上 --user 参数,pip 就会将其安装在当前用户的~/.local/lib/python3.x/site-packages 下,而其他用户的 python 则不会受影响。pip install --user pkg来举个例子# 在全局环境中未安装 requests [root@localhost ~]# pip list | grep requests    [root@localhost ~]# su - wangbm [root@localhost ~]#  # 由于用户环境继承自全局环境,这里也未安装 [wangbm@localhost ~]# pip list | grep requests  [wangbm@localhost ~]# pip install --user requests   [wangbm@localhost ~]# pip list | grep requests  requests (2.22.0) [wangbm@localhost ~]#  # 从 Location 属性可发现 requests 只安装在当前用户环境中 [wangbm@ws_compute01 ~]$ pip show requests --- Metadata-Version: 2.1 Name: requests Version: 2.22.0 Summary: Python HTTP for Humans. Home-page: http://python-requests.org Author: Kenneth Reitz Author-email: me@kennethreitz.org Installer: pip License: Apache 2.0 Location: /home/wangbm/.local/lib/python2.7/site-packages [wangbm@localhost ~]$ exit logout # 退出 wangbm 用户,在 root 用户环境中发现 requests 未安装 [root@localhost ~]$ pip list | grep requests [root@localhost ~]$当你身处个人用户环境中,python 导包时会先检索当前用户环境中是否已安装这个包,已安装则优先使用,未安装则使用全局环境中的包。验证如下:>>> import sys >>> from pprint import pprint  >>> pprint(sys.path) ['',  '/usr/lib64/python27.zip',  '/usr/lib64/python2.7',  '/usr/lib64/python2.7/plat-linux2',  '/usr/lib64/python2.7/lib-tk',  '/usr/lib64/python2.7/lib-old',  '/usr/lib64/python2.7/lib-dynload',  '/home/wangbm/.local/lib/python2.7/site-packages',  '/usr/lib64/python2.7/site-packages',  '/usr/lib64/python2.7/site-packages/gtk-2.0',  '/usr/lib/python2.7/site-packages',  '/usr/lib/python2.7/site-packages/pip-18.1-py2.7.egg',  '/usr/lib/python2.7/site-packages/lockfile-0.12.2-py2.7.egg'] >>>3.6 延长超时时间若网络情况不是很好,在安装某些包时经常会因为 ReadTimeout 而失败。对于这种情况,一般重试几次就好了。但是这样难免有些麻烦,有没有更好的解决方法呢?有的,可以通过延长超时时间。$ pip install --default-timeout=100 <packages>4. 卸载软件包就一条命令,不再赘述$ pip uninstall pkg5. 升级软件包想要对现有的 python 进行升级,其本质上也是先从 pypi 上下载最新版本的包,再对其进行安装。所以升级也是使用 pip install,只不过要加一个参数 --upgrade。$ pip install --upgrade pkg在升级的时候,其实还有一个不怎么用到的选项 --upgrade-strategy,它是用来指定升级策略。它的可选项只有两个:eager :升级全部依赖包only-if-need:只有当旧版本不能适配新的父依赖包时,才会升级。在 pip 10.0 版本之后,这个选项的默认值是 only-if-need,因此如下两种写法是一互致的。pip install --upgrade pkg1  pip install --upgrade pkg1 --upgrade-strategy only-if-need6. 配置文件由于在使用 pip 安装一些包时,默认会使用 pip 的官方源,所以经常会报网络超时失败。常用的解决办法是,在安装包时,使用 -i 参数指定一个国内的镜像源。但是每次指定就很麻烦呀,还要打超长的一串字母。这时候,其实可以将这个源写进 pip 的配置文件里。以后安装的时候,就默认从你配置的这个 源里安装了。那怎么配置呢?文件文件在哪?使用win+r 输入 %APPDATA% 进入用户资料文件夹,查看有没有一个 pip 的文件夹,若没有则创建之。然后进入这个 文件夹,新建一个 pip.ini 的文件,内容如下[global] time-out=60 index-url=https://pypi.tuna.tsinghua.edu.cn/simple/ [install] trusted-host=tsinghua.edu.cn以上几乎包含了 pip 的所有常用使用场景.
  • [技术干货] python 反爬处理的实现
    Cookies的处理作用保存客户端的相关状态在爬虫中如果遇到了cookie的反爬如何处理?手动处理    在抓包工具中捕获cookie,将其封装在headers中    应用场景:cookie没有有效时长且不是动态变化自动处理 使用session机制 使用场景:动态变化的cookie session对象:该对象和requests模块用法几乎一致.如果在请求的过程中产生了cookie,如果该请求使用session发起的,则cookie会被自动存储到session中.案例爬取雪球网中的新闻资讯数据:https://xueqiu.com/1234567891011121314151617#获取一个session对象import requestsheaders = {  'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}session = requests.Session()main_url = 'https://xueqiu.com' #推测对该url发起请求会产生cookiesession.get(main_url,headers=headers)url = 'https://xueqiu.com/v4/statuses/public_timeline_by_category.json'params = {  'since_id': '-1',  'max_id': '20346152',  'count': '15',  'category': '-1',}page_text = session.get(url,headers=headers,params=params).json()page_text
  • [技术干货] Python中使用aiohttp模拟服务器出现错误
    软件版本及环境:Python 3.9 + pycharm 2020.2.1 + Windows10 运行报错: DeprecationWarning: loop argument is deprecatedapp = web.Application(loop=loop)DeprecationWarning: Application.make_handler(…) is deprecated, use AppRunner API insteadsrv = await loop.create_server(app.make_handler(), ‘127.0.0.1', 8000) 出错代码1234567async def init(loop):  app = web.Application(loop=loop)  app.router.add_route('GET', '/', index)  app.router.add_route('GET', '/hello/{name}', hello)  srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8000)  print("Server started at http://127.0.0.1:8000...")  return srv解决方法 删除loop=loop1app = web.Application()将app.make_handler()改为app()1srv = await loop.create_server(app(), '127.0.0.1', 8000)运行结果Server started at http://127.0.0.1:8000...出错原因新版本改动了库函数的使用
  • [技术干货] Python爬虫入门实例之爬取软科中国大学排名
    一、爬取原界面1.网站连接链接:https://www.shanghairanking.cn/rankings/bcur/2020.2.爬取内容  本例爬取的是下图的排名、大学名称、总分三个内容。二、编程思路1.功能描述输入:大学排名URL链接输出:大学排名信息的屏幕输出(排名,大学名称,总分)技术路线:requests­–bs4定向爬虫:仅对输入URL进行爬取,不扩展爬取注:requestts和bs4库的使用只能获取静态页面的信息,如何获取动态页面信息,我会在后边专门写篇文章详细说明2.程序的结构设计步骤一:从网络上获取大学排名网页内容:定义函数getHTMLText()步骤二:提取网页内容中信息到合适的数据结构:定义函数fillUnivList()步骤三:利用数据结构展示并输出结果:定义函数printUnivList()三、编写函数  在编写函数前,首先我们要先看一下网页的源代码通过对网页源代码的观察,我们可以看到,所有大学信息被封装在一个表格中,这个表格的标签叫tbody,在tbody中,每个大学的信息被封装在一个标签中,这个标签叫tr,每个tr标签里又有一个td标签,每个大学的具体信息就被这个标签包围,但是大学的名字是被包在a标签中的,这里要做处理。  所以我们首先遍历tbody标签,获得所有大学信息,然后在tbody标签中找到tr标签,获得每个大学信息,最后在tr标签里找到td标签,把我们需要的相关数据写在我们的ulist列表中。注:  1.由于大学名称被a标签包含,所以我们可以定义一个列表存放a标签内容(与td标签区别开)。  2.为了视觉方面更加美观,可采用中文字符的空格填充 chr(12288),其实就是为了对齐。1.函数getHTMLText()  从网络上获取大学排名网页内容。def getHTMLText(url):#获取URL信息,输出内容    try:        r = requests.get(url,timeout = 30)        r.raise_for_status()        r.encoding = r.apparent_encoding        return r.text    except:        return""2.函数fillUnivList()  提取网页内容中信息到合适的数据结构.def fillUnivList(ulist,html):#将html页面放到ulist列表中(核心)    soup = BeautifulSoup(html,"html.parser")    for tr in soup.find('tbody').children:        if isinstance(tr,bs4.element.Tag):#如果tr标签的类型不是bs4库中定义的tag类型,则过滤掉            a = tr('a')#将所有的a标签存为一个列表类型            tds = tr('td')#将所有的td标签存为一个列表类型            ulist.append([tds[0].string.strip(),a[0].string.strip(),tds[4].string.strip()])注:这里要注意的是,要注意使用strip()函数,它的作用是用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。但该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。用在此处可以使爬取的内容,在格式化输出时达到对齐的效果。3.函数printUnivList()  利用数据结构展示并输出结果:定义函数。def printUnivList(ulist1,num):#打印出ulist列表的信息,num表示希望将列表中的多少个元素打印出来    #格式化输出    tplt = "{0:^10}\t{1:{3}^12}\t{2:^10}"    # 0、1、2为槽,{3}表示若宽度不够,使用format的3号位置处的chr(12288)(中文空格)进行填充    print(tplt.format("排名","学校名称","总分",chr(12288)))    for i in range(num):        u = ulist1[i]        print(tplt.format(u[0], u[1], u[2],chr(12288)))    print()    print("共有记录"+str(num)+"条")四、完整代码'''功能描述:输入:大学排名URL输出:大学排名信息的屏幕输出(排名,大学名称,总分)技术路线:requests—bs4(只能获取静态页面信息)定向爬虫:仅对输入URL进行爬取,不扩展爬取程序的结构设计:1.从网络上获取大学排名网页内容:定义函数getHTMLText()2.提取网页内容中信息到合适的数据结构:定义函数fillUnivList()3.利用数据结构展示并输出结果:定义函数printUnivList()'''import requestsfrom bs4 import BeautifulSoupimport bs4ulist1=[]def getHTMLText(url):#获取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):#将html页面放到ulist列表中(核心)    soup = BeautifulSoup(html,"html.parser")    for tr in soup.find('tbody').children:        if isinstance(tr,bs4.element.Tag):#如果tr标签的类型不是bs4库中定义的tag类型,则过滤掉            a = tr('a')            tds = tr('td')#将所有的td标签存为一个列表类型            ulist.append([tds[0].string.strip(),a[0].string.strip(),tds[4].string.strip()])def printUnivList(ulist1,num):#打印出ulist列表的信息,num表示希望将列表中的多少个元素打印出来    #格式化输出    tplt = "{0:^10}\t{1:{3}^12}\t{2:^10}"    # 0、1、2为槽,{3}表示若宽度不够,使用format的3号位置处的chr(12288)(中文空格)进行填充    print(tplt.format("排名","学校名称","总分",chr(12288)))    for i in range(num):        u = ulist1[i]        print(tplt.format(u[0], u[1], u[2],chr(12288)))    print()    print("共有记录"+str(num)+"条")def main():    uinfo = [] #将大学信息放到列表中    url = "https://www.shanghairanking.cn/rankings/bcur/2020"    html = getHTMLText(url)    fillUnivList(uinfo,html)    printUnivList(uinfo,10)main()输出效果如下图:
  • [互动交流] CloudIDE python3 turtle安装问题
    上午试了下,增加多版本的python,换了个网络,安装包下载下来了,安装不了,提示有些文件夹没有权限修改。晚上想跑个程序,用到turtle库,安装不了。搜了下,问题提示的大概率是由于python版本2.7与3.7的语言写法区别,带括号与不带括号。试图修改这个文件的时候,未能修改成功。现在对terminal的文件结构还有点懵。求大神帮渡个劫~
  • [互动交流] CloudIDE+python多版本安装问题求助
    手册上提到可以点击左下角任务条更换python版本,试了下,发现只有3.7.0的。尝试命令行窗口下载2.7的python安装包,官网的很慢啊~请问有没有别的源可以用?
  • [技术干货] Python猜单词小游戏(简约版)
    猜单词游戏思路一个words列表里存放若干的单词,例如:在words列表里随机取出一个单词放进word列表,例如:用一个tips列表存放提示信息,长度跟随机取出来的单词长度相同,而且初始化如下图:一个列表放随机数,长度跟随机取出来的单词长度相同的,且不重复。当用随机数列表里的前两个元素,用word列表里的元素替换提示信息列表的元素:剩下就是游戏逻辑了,需要提示的时候,遍历下一个随机数列表,然后替换信息直接上代码:import random#初始化信息↓↓↓↓↓↓↓# 存放单词的列表words = ["extends", "private", "static", "public", "void", "return", "super","package","throws"]#随机获取单词列表里的一个单词word = list(words[random.randint(0, len(words) - 1)])#随机数列表,存放着与单词长度一致的随机数(不重复)ranList = random.sample(range(0, len(word)), len(word))#存放提示信息tips = list()#初始化提示信息#存放跟单词长度一致的下划线for i in range(len(word)):tips.append("_")#随机提示两个字母tips[ranList[0]] = word[ranList[0]]tips[ranList[1]] = word[ranList[1]]#函数部分↓↓↓↓↓#展示菜单def showMenu():print("需要提示请输入'help?'")print("结束游戏请输入'quit!'")#显示提示信息def showtips():for i in tips:print(i, end=" ")print()#需要提示def needTips(tipsSize):#至少有两个未知字母if tipsSize <= len(word)-3:tips[ranList[tipsSize]] = word[ranList[tipsSize]]tipsSize += 1return tipsSizeelse:print("已没有提示!")#主要运行函数↓↓↓↓↓↓def init():print("------java关键字版本-------")tipsSize = 2showMenu()while True:print("提示:",end="")showtips()guessWord = input("猜一下这个单词:")#  <''.join(word)>把word列表的内容转换成字符串if guessWord == ''.join(word):print("恭喜你,猜对了!就是%s!"%(''.join(word)))breakelif guessWord == 'help?':tipsSize = needTips(tipsSize)elif guessWord == 'quit!':breakelse:print("猜错了!")continueinit()运行结果:
  • [技术干货] 推荐一个好玩的python闯关游戏
    http://www.pythonchallenge.com/点进去是这样的    提示是改URL地址,改成这样http://www.pythonchallenge.com/pc/def/238.html额,进一步提示,哈,计算器上来,2^38=274877906944bingo,下一关。好玩~
  • [技术干货] 【转载】Python程序员:没有我蹭不成功的网。教你如何愉快的蹭到WIFI?
    想象一下,程序员没有WIFI会怎样?程序员没有网络肯定会寸步难行!但是对于Python程序员来说,只要附近有热点,分分钟就能蹭网成功!想要WIFI破解,python+字典,这是必少不了的。热点加弱口令也是核心。字典自己加精,你的字典有强大,你能破解的WIFI就越多,提供两种方法,一般人学到一种即可。方法一1.环境准备python2.7pywifi模块字典清除系统中的任何wifi连接记录2.导入模块这里用的模块就这三个 pywifi的_wifiutil_linux.py脚本的 _send_cmd_to_wpas方法中的if reply != b'OK ':判断需要修改,不然会有很多的提示信息。3.字典准备随机搞的wifi弱口令TOP104.配置扫描器推荐扫描时常可以设置在15-20秒之间 测试时常则可以自定义,考虑到认证速度于距离的关系,我一般设置在15左右,再久的也没意义 到时候就算破解成功的热点,信号也好不到哪里。5.扫描周围热点6.热点测试这里后续推荐将扫描过程数据入库,防止重复扫描,且更加直观。这里显示本次测试使用了11个弱口令,并扫描到了20个热点,然后开始坑爹的跑起来了:WIFIID 热点的id号 每跑一个会减1SSID OR BSSID 热点的ssid名或mac地址N 对热点的连接状态,这个在time 当前所花去的时间signal 热点的信号强度,若小越好KEYNUM 测试密码的id 每跑一个会减1KEY 当前测试的密码方法二目前常见的WiFi加密方式有WEP、WPA2和WPS(链接为各自的破解方式),不过有网友反映以往破解WPA2的方法耗时太长,而且不适用于所有WPS启动的接入点。而今天介绍的这种方法则更加省时省力。1.主要原理创建一个伪AP来“狸猫换**”,然后撤销用户AP的授权,通知用户需要进行“固件升级”,需要重新验证密码。你的假AP由于具有相同的SSID,用户便会“交代”密码。这样你就能得到用户的密码,并且让用户采用你的伪AP做为自己的接入点。而对方一无所知。之前也有类似的脚本,例如Airsnarf;不过我们这次采用的Wifiphisher,这个优化过的自动化脚本比起前者更加方便。要完成上述“大业”,你需要Kali Linux和两个无线适配器,其中一个必须能支持数据包注入。2.第一步:下载Wifiphisher如图所示,这是已经解开了的Wifiphisher源代码。当然,如果你懒,也可以复制GitHub上的代码,不用谢~3.第二步:导航到该目录接下来,导航到Wifiphisher创建时被解压的目录。就图示而言,为/wifiphisherWi-Fi1.1。当你看到目录内容时,你会看到wifiphisher.py的脚本。4.第三步:运行脚本可以键入下面的脚本实现。注意这里有一个问题:如果是第一次运行脚本的话,它可能会出现提示安装hostpad的信息,键入Y继续安装即可。完成的时候,再次运行Wifiphisher脚本。这次将运行8080和43端口的Web服务器,然后开始搜索附近的Wi-Fi网络。等待搜索完成,我们会发现一系列Wi-Fi网络名。最下方的wonderhowto就是我们的目标。5.第四步:获取密码按下Ctrl + C,键入想要复制的AP数,在这里我们选择12。敲下回车,Wifiphisher会显示如下结果,显示了正在使用的界面,还有正被攻击及复制的AP所在的SSID。目标用户已经取消验证他们的AP,随后会出现一个固件升级的信息,请求他们重新验证。一旦重新验证,他们接入的就是伪接入点了。当用户输入密码,它会通过Wifiphisher的开放终端传输给你,随后他们依然像平时一样上网,风平浪静,然而他们并不知道我们已经获得了密码。现在你可以开始愉快地蹭WiFi了!
  • [技术干货] [转载]Python IO模型之非阻塞IO(non-blocking IO)
    非阻塞IO(non-blocking IO)Linux下,可以通过设置socket使其变为non-blocking。当对一个non-blocking socket执行读操作时,流程是这个样子:从图中可以看出,当用户进程发出read操作时,如果kernel中的数据还没有准备好,那么它并不会block用户进程,而是立刻返回一个error。从用户进程角度讲 ,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果。用户进程判断结果是一个error时,它就知道数据还没有准备好,于是用户就可以在本次到下次再发起read询问的时间间隔内做其他事情,或者直接再次发送read操作。一旦kernel中的数据准备好了,并且又再次收到了用户进程的system call,那么它马上就将数据拷贝到了用户内存(这一阶段仍然是阻塞的),然后返回。    也就是说非阻塞的recvform系统调用调用之后,进程并没有被阻塞,内核马上返回给进程,如果数据还没准备好,此时会返回一个error。进程在返回之后,可以干点别的事情,然后再发起recvform系统调用。重复上面的过程,循环往复的进行recvform系统调用。这个过程通常被称之为轮询。轮询检查内核数据,直到数据准备好,再拷贝数据到进程,进行数据处理。需要注意,拷贝数据整个过程,进程仍然是属于阻塞的状态。    所以,在非阻塞式IO中,用户进程其实是需要不断的主动询问kernel数据准备好了没有。非阻塞IO实例:#服务端 from socket import * import time s=socket(AF_INET,SOCK_STREAM) s.bind(('127.0.0.1',8080)) s.listen(5) s.setblocking(False) #设置socket的接口为非阻塞 conn_l=[] del_l=[] while True:     try:         conn,addr=s.accept()         conn_l.append(conn)     except BlockingIOError:         print(conn_l)         for conn in conn_l:             try:                 data=conn.recv(1024)                 if not data:                     del_l.append(conn)                     continue                 conn.send(data.upper())             except BlockingIOError:                 pass             except ConnectionResetError:                 del_l.append(conn)         for conn in del_l:             conn_l.remove(conn)             conn.close()         del_l=[] #客户端 from socket import * c=socket(AF_INET,SOCK_STREAM) c.connect(('127.0.0.1',8080)) while True:     msg=input('>>: ')     if not msg:continue     c.send(msg.encode('utf-8'))     data=c.recv(1024)     print(data.decode('utf-8'))但是非阻塞IO模型绝不被推荐。    我们不能否则其优点:能够在等待任务完成的时间里干其他活了(包括提交其他任务,也就是 “后台” 可以有多个任务在“”同时“”执行)。    但是也难掩其缺点:#1. 循环调用recv()将大幅度推高CPU占用率;这也是我们在代码中留一句time.sleep(2)的原因,否则在低配主机下极容易出现卡机情况 #2. 任务完成的响应延迟增大了,因为每过一段时间才去轮询一次read操作,而任务可能在两次轮询之间的任意时间完成。这会导致整体数据吞吐量的降低。此外,在这个方案中recv()更多的是起到检测“操作是否完成”的作用,实际操作系统提供了更为高效的检测“操作是否完成“作用的接口,例如select()多路复用模式,可以一次检测多个连接是否活跃。
  • [技术干货] python之封装
    【封装】         隐藏对象的属性和实现细节,仅对外提供公共访问方式。【好处】 1. 将变化隔离; 2. 便于使用;3. 提高复用性; 4. 提高安全性;【封装原则】      1. 将不需要对外提供的内容都隐藏起来;      2. 把属性都隐藏,提供公共方法对其访问。1、私有变量和私有方法在python中用双下划线开头的方式将属性隐藏起来(设置成私有的)1)、私有变量#其实这仅仅这是一种变形操作#类中所有双下划线开头的名称如__x都会自动变形成:_类名__x的形式:class A:    __N=0 #类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N    def __init__(self):         self.__X=10 #变形为self._A__X    def __foo(self): #变形为_A__foo        print('from A')     def bar(self):         self.__foo() #只有在类内部才可以通过__foo的形式访问到.#A._A__N是可以访问到的,即这种操作并不是严格意义上的限制外部访问,仅仅只是一种语法意义上的变形这种自动变形的特点:1.类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。2.这种变形其实正是针对外部的变形,在外部是无法通过__x这个名字访问到的。3.在子类定义的__x不会覆盖在父类定义的__x,因为子类中变形成了:_子类名__x,而父类中变形成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是无法覆盖的。这种变形需要注意的问题是:1.这种机制也并没有真正意义上限制我们从外部直接访问属性,知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如a._A__N2.变形的过程只在类的内部生效,在定义后的赋值操作,不会变形2)、私有方法3.在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的#正常情况>>> class A:...     def fa(self): ...         print('from A') ...     def test(self): ...         self.fa() ... >>> class B(A):...     def fa(self): ...         print('from B') ... >>> b=B()>>> b.test() from B  #把fa定义成私有的,即__fa>>> class A:...     def __fa(self): #在定义时就变形为_A__fa...         print('from A') ...     def test(self): ...         self.__fa() #只会与自己所在的类为准,即调用_A__fa... >>> class B(A):...     def __fa(self): ...         print('from B') ... >>> b=B()>>> b.test() from A2、封装与扩展性封装在于明确区分内外,使得类实现者可以修改封装内的东西而不影响外部调用者的代码;而外部使用用者只知道一个接口(函数),只要接口(函数)名、参数不变,使用者的代码永远无需改变。这就提供一个良好的合作基础——或者说,只要接口这个基础约定不变,则代码改变不足为虑。#类的设计者class Room:    def __init__(self,name,owner,width,length,high):         self.name=name         self.owner=owner         self.__width=width         self.__length=length         self.__high=high     def tell_area(self): #对外提供的接口,隐藏了内部的实现细节,此时我们想求的是面积        return self.__width * self.__length#使用者>>> r1=Room('卧室','egon',20,20,20)>>> r1.tell_area() #使用者调用接口tell_area#类的设计者,轻松的扩展了功能,而类的使用者完全不需要改变自己的代码class Room:    def __init__(self,name,owner,width,length,high):         self.name=name         self.owner=owner         self.__width=width         self.__length=length         self.__high=high     def tell_area(self): #对外提供的接口,隐藏内部实现,此时我们想求的是体积,内部逻辑变了,只需求修该下列一行就可以很简答的实现,而且外部调用感知不到,仍然使用该方法,但是功能已经变了        return self.__width * self.__length * self.__high#对于仍然在使用tell_area接口的人来说,根本无需改动自己的代码,就可以用上新功能>>> r1.tell_area()3、property属性什么是特性propertyproperty是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解) 成人的BMI数值: 过轻:低于18.5 正常:18.5-23.9 过重:24-27 肥胖:28-32 非常肥胖, 高于32   体质指数(BMI)=体重(kg)÷身高^2(m)   EX:70kg÷(1.75×1.75)=22.86class People:    def __init__(self,name,weight,height):         self.name=name         self.weight=weight         self.height=height     @property     def bmi(self):         return self.weight / (self.height**2) p1=People('egon',75,1.85) print(p1.bmi)import mathclass Circle:    def __init__(self,radius): #圆的半径radius        self.radius=radius     @property     def area(self):        return math.pi * self.radius**2 #计算面积    @property     def perimeter(self):        return 2*math.pi*self.radius #计算周长c=Circle(10) print(c.radius) print(c.area) #可以向访问数据属性一样去访问area,会触发一个函数的执行,动态计算出一个值print(c.perimeter) #同上''' 输出结果: 314.1592653589793 62.83185307179586 '''#注意:此时的特性area和perimeter不能被赋值c.area=3 #为特性area赋值''' 抛出异常: AttributeError: can't set attribute '''为什么要用property将一个类的函数定义成特性以后,对象再去使用的时候obj.name,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则除此之外,看下ps:面向对象的封装有三种方式: 【public】 这种其实就是不封装,是对外公开的 【protected】 这种封装方式对外不公开,但对朋友(friend)或者子类(形象的说法是“儿子”,但我不知道为什么大家 不说“女儿”,就像“parent”本来是“父母”的意思,但中文都是叫“父类”)公开 【private】 这种封装对谁都不公开python并没有在语法上把它们三个内建到自己的class机制中,在C++里一般会将所有的所有的数据都设置为私有的,然后提供set和get方法(接口)去设置和获取,在python中通过property方法可以实现class Foo:    def __init__(self,val):         self.__NAME=val #将所有的数据属性都隐藏起来    @property     def name(self):         return self.__NAME #obj.name访问的是self.__NAME(这也是真实值的存放位置)    @name.setter     def name(self,value):         if not isinstance(value,str):  #在设定值之前进行类型检查            raise TypeError('%s must be str' %value)         self.__NAME=value #通过类型检查后,将值value存放到真实的位置self.__NAME    @name.deleter     def name(self):         raise TypeError('Can not delete') f=Foo('egon') print(f.name)# f.name=10 #抛出异常'TypeError: 10 must be str'del f.name #抛出异常'TypeError: Can not delete'一个静态属性property本质就是实现了get,set,delete三种方法class Foo:    @property     def AAA(self):         print('get的时候运行我啊')     @AAA.setter     def AAA(self,value):         print('set的时候运行我啊')     @AAA.deleter     def AAA(self):         print('delete的时候运行我啊')#只有在属性AAA定义property后才能定义AAA.setter,AAA.deleterf1=Foo() f1.AAA f1.AAA='aaa'del f1.AAAclass Foo:    def get_AAA(self):        print('get的时候运行我啊')     def set_AAA(self,value):        print('set的时候运行我啊')     def delete_AAA(self):        print('delete的时候运行我啊')     AAA=property(get_AAA,set_AAA,delete_AAA) #内置property三个参数与get,set,delete一一对应f1=Foo() f1.AAA f1.AAA='aaa'del f1.AAA怎么用?class Goods:    def __init__(self):         # 原价        self.original_price = 100        # 折扣        self.discount = 0.8    @property     def price(self):         # 实际价格 = 原价 * 折扣        new_price = self.original_price * self.discount         return new_price     @price.setter     def price(self, value):         self.original_price = value     @price.deleter     def price(self):         del self.original_price obj = Goods() obj.price         # 获取商品价格obj.price = 200   # 修改商品原价print(obj.price) del obj.price     # 删除商品原价4、classmethodclass Classmethod_Demo():    role = 'dog'    @classmethod     def func(cls):        print(cls.role) Classmethod_Demo.func()5、staticmethodclass Staticmethod_Demo():    role = 'dog'    @staticmethod     def func():         print("当普通方法用") Staticmethod_Demo.func()练习1:class Foo:    def func(self):        print('in father')class Son(Foo):    def func(self):        print('in son') s = Son() s.func()# 请说出上面一段代码的输出并解释原因?练习2:class A:    __role = 'CHINA'    @classmethod     def show_role(cls):         print(cls.__role)     @staticmethod     def get_role():         return A.__role     @property     def role(self):         return self.__role a = A() print(a.role) print(a.get_role()) a.show_role()# __role在类中有哪些身份?# 以上代码分别输出哪些内容?# 这三个装饰器分别起了什么作用?有哪些区别?
  • [技术干货] [转载]Python Collections模块
    在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。1.namedtuple: 生成可以使用名字来访问元素内容的tuple2.deque: 双端队列,可以快速的从另外一侧追加和推出对象3.Counter: 计数器,主要用来计数4.OrderedDict: 有序字典5.defaultdict: 带有默认值的字典1、namedtuple我们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成:>>> p=(2,6)但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的。这时,namedtuple就派上了用场:from collections import namedtuple point = namedtuple("point", ['x', 'y']) print(point) p_obj = point(6, 8) print(p_obj.x) print(p_obj.y)结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo005.py68Process finished with exit code 0类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:# namedtuple('名称', [属性list]):Circle = namedtuple("Circle", ['x', 'y', 'r']) cir = Circle(8, 6, 10) print(cir.x) print(cir.y) print(cir.r)结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo005.py8610Process finished with exit code 02、deque使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:from collections import deque q = deque(['a', 'b', 'c']) q.append('d') print(q) q.appendleft('e') print(q) q.pop() print(q) q.popleft() print(q)结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo005.py deque(['a', 'b', 'c', 'd']) deque(['e', 'a', 'b', 'c', 'd']) deque(['e', 'a', 'b', 'c']) deque(['a', 'b', 'c']) Process finished with exit code 0deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。3、OrderedDict使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。如果要保持Key的顺序,可以用OrderedDict:from collections import OrderedDict lis = [('a', 21), ('b', 55), ('c', 86)] dic = dict(lis)  # dict的Key是无序的print(dic) ord_dic = OrderedDict(lis)  # OrderedDict的Key是有序的print(ord_dic)结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo005.py {'a': 21, 'b': 55, 'c': 86}OrderedDict([('a', 21), ('b', 55), ('c', 86)])Process finished with exit code 0注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:ord_dic = OrderedDict() ord_dic['z'] = 99ord_dic['y'] = 110ord_dic['z'] = 666print(ord_dic.keys())  # 按照插入的Key的顺序返回结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo005.py odict_keys(['z', 'y']) Process finished with exit code 04、defaultdict 有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。即: {'k1': 大于66 , 'k2': 小于66}lis = [11, 22, 33, 55, 77, 66, 88, 99] dic = {}for value in lis:     if value > 66:         if dic.has_key('k1'):             dic['k1'].append(value)         else:             dic['k1'] = [value]     else:         if dic.has_key('k2'):             dic['k2'].append(value)         else:             dic['k2'] = [value]from collections import defaultdictlis = [11, 22, 33, 55, 77, 66, 88, 99]my_dic = defaultdict(lis)for value in lis:    if value > 66:        my_dic['k1'].append(value)    else:        my_dic['k2'].append(value)print(my_dic)使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict:from collections import defaultdict dd = defaultdict(lambda: 'N/A') dd['key1'] = 'abc'  # key1存在print(dd['key1']) print(dd['key2'])  # key2不存在,返回默认值print(dd['key3'])结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo005.py abc N/A N/A Process finished with exit code 05、CounterCounter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。from collections import Counter coun = Counter("absdsdsdadsdsa") print(coun)结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo005.py Counter({'s': 5, 'd': 5, 'a': 3, 'b': 1}) Process finished with exit code 0创建下面的代码说明了Counter类创建的四种方法:from collections import Counterc = Counter()  # 创建一个空的Counter类print(c)c = Counter('g***d')  # 从一个可iterable对象(list、tuple、dict、字符串等)创建print(c)c = Counter({'a': 4, 'b': 2})  # 从一个字典对象创建print(c)c = Counter(a=4, b=2)  # 从一组键值对创建print(c)结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo006.py Counter() Counter({'a': 3, 'l': 2, 'g': 1, 'h': 1, 'd': 1}) Counter({'a': 4, 'b': 2}) Counter({'a': 4, 'b': 2}) Process finished with exit code 0计数值的访问与缺失的键当所访问的键不存在时,返回0,而不是KeyError;否则返回它的计数。计数值的访问from collections import Counter cou = Counter("hello world") print(cou["l"]) print(cou["o"]) print(cou["a"])结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo006.py320Process finished with exit code 0计数器的更新(update和subtract)可以使用一个iterable对象或者另一个Counter对象来更新键值。计数器的更新包括增加和减少两种。其中,增加使用update()方法:计数器的更新(update)from collections import Counter cou = Counter("hello world") cou.update("which")  # 使用另一个iterable对象更新print(cou["h"]) c = Counter("watch") cou.update(c)  # 使用另一个Counter对象更新print(cou["h"])结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo006.py34Process finished with exit code 0减少则使用subtract()方法:计数器的更新(subtract)from collections import Counter c = Counter('which') print(c["h"]) c.subtract('witch')  # 使用另一个iterable对象更新print(c['h']) d = Counter('watch') c.subtract(d)  # 使用另一个Counter对象更新print(c['a'])结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo006.py21-1Process finished with exit code 0键的修改和删除当计数值为0时,并不意味着元素被删除,删除元素应当使用del。 键的删除from collections import Counterc = Counter("abcdcba")print(c)c["b"] = 0print(c) del c["a"]print(c)结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo006.py Counter({'a': 2, 'b': 2, 'c': 2, 'd': 1}) Counter({'a': 2, 'c': 2, 'd': 1, 'b': 0}) Counter({'c': 2, 'd': 1, 'b': 0}) Process finished with exit code 0elements()返回一个迭代器。元素被重复了多少次,在该迭代器中就包含多少个该元素。元素排列无确定顺序,个数小于1的元素不被包含。elements()方法 from collections import Counterc = Counter(a=4, b=2, c=0, d=-2)print(list(c.elements()))结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo006.py ['a', 'a', 'a', 'a', 'b', 'b'] Process finished with exit code 0most_common([n])返回一个TopN列表。如果n没有被指定,则返回所有元素。当多个元素计数值相同时,排列是无确定顺序的。most_common()方法from collections import Counterc = Counter('abracadabra')print(c)print(c.most_common())print(c.most_common(3))结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo006.py Counter({'a': 5, 'b': 2, 'r': 2, 'c': 1, 'd': 1}) [('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)] [('a', 5), ('b', 2), ('r', 2)] Process finished with exit code 0浅拷贝copy浅拷贝copyfrom collections import Counterc = Counter("abcdcba")print(c) d = c.copy()print(d)结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo006.py Counter({'a': 2, 'b': 2, 'c': 2, 'd': 1}) Counter({'a': 2, 'b': 2, 'c': 2, 'd': 1}) Process finished with exit code 0算术和集合操作+、-、&、|操作也可以用于Counter。其中&和|操作分别返回两个Counter对象各元素的最小值和最大值。需要注意的是,得到的Counter对象将删除小于1的元素。Counter对象的算术和集合操作from collections import Counterc = Counter(a=3, b=1) d = Counter(a=1, b=2)print(c + d)  # c[x] + d[x]print(c - d)  # subtract(只保留正数计数的元素)print(c & d)  # 交集:  min(c[x], d[x])print(c | d)  # 并集:  max(c[x], d[x])结果:D:\YuchuanProjectData\PythonProject\venv\Scripts\python.exe D:/YuchuanProjectData/PythonProject/YuchuanDemo006.py Counter({'a': 4, 'b': 3}) Counter({'a': 2}) Counter({'a': 1, 'b': 1}) Counter({'a': 3, 'b': 2}) Process finished with exit code 0其他常用操作下面是一些Counter类的常用操作,来源于Python官方文档Counter类常用操作sum(c.values())  # 所有计数的总数c.clear()  # 重置Counter对象,注意不是删除list(c)  # 将c中的键转为列表set(c)  # 将c中的键转为setdict(c)  # 将c中的键值对转为字典c.items()  # 转为(elem, cnt)格式的列表Counter(dict(list_of_pairs))  # 从(elem, cnt)格式的列表转换为Counter类对象c.most_common()[:-n:-1]  # 取出计数最少的n个元素c += Counter()  # 移除0和负值
  • [技术干货] 【转载】Python如何安装第三方模块
    Python中有哪几种方法安装第三方模块,安装Python第三方模块的方法有很多,这里介绍三种方法安装第三方模块。【方法一】: 通过setuptools来安装python模块首先下载 http://peak.telecommunity.com/dist/ez_setup.pyNOTE: 最好下载个setuptools,本人是15.2版本,里面包含了ez_setup运行 python ez_setup.pyD:\work\installation\setuptools-15.2\setuptools-15.2>python ez_setup.py > 1.txtExtracting in c:\users\admini~1\appdata\local\temp\tmpbxikxf Now working in c:\users\admini~1\appdata\local\temp\tmpbxikxf\setuptools-15.2Installing Setuptools  ...... Copying setuptools-15.2-py2.7.egg to c:\python27\lib\site-packages  setuptools 15.2 is already the active version in easy-install.pth Installing easy_install-script.py script to C:\Python27\Scripts Installing easy_install.exe script to C:\Python27\Scripts Installing easy_install-2.7-script.py script to C:\Python27\Scripts Installing easy_install-2.7.exe script to C:\Python27\Scripts Installed c:\python27\lib\site-packages\setuptools-15.2-py2.7.eggProcessing dependencies for setuptools==15.2Finished processing dependencies for setuptools==15.2运行 easy_install pyD:\work>easy_install py   #py 为第三方库文件 Searching for py Best match: py 1.4.26Adding py 1.4.26 to easy-install.pth fileUsing c:\python27\lib\site-packages Processing dependencies for py Finished processing dependencies for py【方法二】: 通过pip来安装python模块安装 easy_install pipD:\work>easy_install pip Searching for pip Best match: pip 6.1.1Processing pip-6.1.1-py2.7.eggpip 6.1.1 is already the active version in easy-install.pth Installing pip-script.py script to C:\Python27\Scripts Installing pip.exe script to C:\Python27\Scripts Installing pip2.7-script.py script to C:\Python27\Scripts Installing pip2.7.exe script to C:\Python27\Scripts Installing pip2-script.py script to C:\Python27\Scripts Installing pip2.exe script to C:\Python27\Scripts Using c:\python27\lib\site-packages\pip-6.1.1-py2.7.eggProcessing dependencies for pip Finished processing dependencies for pip运行 pip install xlrdUsage:    pip  [options]  Commands:   install      Install packages.   uninstall     Uninstall packages.   freeze      Output installed packages in requirements format.   list      List installed packages.   show      Show information about installed packages.   search      Search PyPI for packages.   wheel      Build wheels from your requirements.   zip       DEPRECATED. Zip individual packages.   unzip      DEPRECATED. Unzip individual packages.   help      Show help for commands. General Options:   -h, --help     Show help.  --isolated     Run pip in an isolated mode, ignoring  environment variables and user configuration.   -v, --verbose    Give more output. Option is additive, and can be  used up to 3 times.   -V, --version    Show version and exit.  -q, --quiet     Give less output.  --log     Path to a verbose appending log.  --proxy     Specify a proxy in the form  [user:passwd@]proxy.server:port.   --retries    Maximum number of retries each connection should  attempt (default 5 times).   --timeout     Set the socket timeout (default 15 seconds).  --exists-action  Default action when a path already exists:  (s)witch, (i)gnore, (w)ipe, (b)ackup.   --trusted-host  Mark this host as trusted, even though it does  not have valid or any HTTPS.   --cert     Path to alternate CA bundle.  --client-cert   Path to SSL client certificate, a single file containing the private key and the certificate   in PEM format.   --cache-dir    Store the cache data in .  --no-cache-dir    Disable the cache.  --disable-pip-version-check  Don't periodically check PyPI to determine   whether a new version of pip is available for  download. Implied with --no-index.【方法三】:直接从网上下载下可执行文件来安装.比如说,去 >>> pythonlibs <<< 网站,提供了很多Python非官方包下载,二进制文件,下载安装方便。到此这篇关于Python如何安装第三方模块的文章就介绍到这了,更多相关Python安装第三方模块的方法内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!文章来源: blog.51cto.com,作者:wx5ecc6bcb4713c,版权归原作者所有,如需转载,请联系作者。原文链接:https://blog.51cto.com/14825302/2515095
  • [技术干货] python生成4人扑克手牌
    '''2 随机生成扑克牌的4手牌(4个人的牌局,没手13张,没有大小王)'''import random num = []#代表红桃,方块,黑桃,梅花for i in ['Hearts','Cube','Spades','plum']:     for j in ['2','3','4','5','6','7','8','9','10','J','Q','K','A']:         num.append(i+j)#random.shuffle() 讲序列中的内容随机打乱random.shuffle(num)#生成二维gamegame = [[] for i in range(4)]#一次性发13张''' for i in range(4):         while len(num) > 0:         game[i].append(num[0])         num.pop(0)         if len(game[i])==13 :             break for i in range(4):     print("第{}个人的手牌为:\n".format(i+1),game[i]) '''#一次发一张for i in range(52):     if len(num) == 0:         break     game[i%4].append(num[0])     #删除第一个元素     num.pop(0)for i in range(4):     print("第{}个人的手牌为:\n".format(i+1),game[i])12345678910111213141516171819202122232425262728293031两个方法生成,注释掉的内容为一次发够13张
  • [技术干货] 用Python解决海量数据的分类汇总~一键化办公的神器
    项目引入昨天突然发现有一个比较头疼的问题,有一份数据是某一个学校的寝室数据,有不同的维度的分类,总的数据大概有4000数据,需要进行分类,然后按照不同分类维度进行表格制作,最后生成8个文件夹,每个文件夹里面有24个表格,这个就是我们这一个程序的最终实现功能。如果我们用Excel筛选需要点很多次,而且需要几个人的配合工作,这样就比较的费力,那么作为数据分析的Python神器,可不可以解决这个问题了,答案是当然可以!项目思路1.首先对这个大量的数据进行导入,用CSV这个库,然后按照Python的对象进行写入和解析,最后存储在pycharm运行内存空间,方便我们下一步操作。2.导入之后我们就需要分类了,这个时候需要我们写一个算法了,我把它叫做“字典迭代算法”当然是我自己命名的,这个里面涉及到很多的坑,最后我们需要把这个功能封装起来。3.数据保存也就是,CSV文件的写入数据,最后利用Python的内置模块OS进行文件夹的分类创建,最后实现保存数据,这个时候我们还要解决CSV文件的中文乱码问题。难点1.解析数据之后如何分割数据,进行保存2.写入文件的时候如何解决乱码问题3.怎样去结构化我们的代码程序代码介绍大概的思路就是这样,下面我们来具体看看这个程序的功能实现的功能步骤解析数据# 1.解析CSV海量数据,用字典保存在内存空间def csv_data():     global dormitory_data    import csv     dormitory_data = []     with open(r"寝室数据.csv", encoding='utf-8-sig') as file:#将你的CSV文件和该程序文件放在一个文件夹下面         f_csv = csv.reader(file)#读取文件里面的每一行数据,转换为列表赋值给新的变量         header = next(f_csv)#利用迭代的方法,直接取出表头行(标题行),更新f_csv的数据,去除了标题行         for row in f_csv:             data = {}             for index in range(7):                 data[header[index]] = row[index]             dormitory_data.append(data)12345678910111213这里我们对一份Excel的数据,修改它的后缀名,变成CSV文件的后缀名即可,然后我们就对这个数据进行导入和解析了。这个解析过程和我们之前的一篇文章《用Python写一个成绩计算系统》的有异曲同工之妙。主要要理解对表头行的提取很数据迭代解析,最后存储在一个列表里面。注意这里一般都是需要声明全局变量的。效果执行分割数据# 分割数据,按照数据的特点def csv_sort():     global dicts     dicts=[];i = 0     dormitory_datas = dormitory_data.copy()#字典迭代删除迭代数据是一个坑,需要我们时刻更新数据库值     dormitory_datass= dormitory_data.copy()     for x in dormitory_datass:         b = []         for sort in dormitory_datass:             a_1 = sort["宿舍编号"]             b.append(a_1)         dicts.append(x)         dormitory_data.remove(x)         dormitory_datass=dormitory_data.copy()         if b[i][:3] != b[i+1][:3]:             break1234567891011121314151617这里不要小看这个几行代码,这个里面的算法是需要进行反复的测试,才实行的,里面有几个坑,真的是有点头疼,还好最后解决了。1.首先我们要按照一个算法去分割数据,我们浏览数据之后发现,每一个组团的1-4栋寝室数据都是有相关联的,1楼到2楼的寝室编号我们按照前三位的数据节点,进行索引判断,这样去迭代每一个数据,然后进行比较,最后如果不同的话,我们就发现那么肯定是不同的楼层了,需要我们进行分割数据了。2.但是我们发现我们跳出循环之后,也就是迭代完1楼的寝室数据之后,我们惊奇的字典的数据虽然是变化了,但是唯独也发生了变化,这个就是第一个坑,因为列表的删除有一个特点,它是利用迭代索引进行删除的,这个在我之前的计算机二级Python程序语言设计-疑难杂症知识点汇总,提到了这个解决办法。我最后利用字典的复制存储,不断的去更新和弥补这个数据字典,bug才解决,这个时候真的需要静下心来慢慢思索。3.利用字典迭代算法,判断什么时候需要分割数据,最后封装这个函数功能。保存数据#保存数据,按照不同的分类def keep_data():     import csv    import os    import codecs    for w in range(65,73):         W=chr(w)         path = '%s栋寝室'%W      # 创建总的文件夹         if not os.path.exists(path):             os.mkdir(path)             os.chdir(path)         else:             os.chdir(path)         a = []         dict = dormitory_data[0]         for headers in dict.keys():  # 把字典的键取出来,注意不要使用sorted不然会导致键的顺序改变             a.append(headers)         header = a  # 把列名给提取出来,用列表形式呈现         for k in range(1,5):             K=k            for p in range(1,7):                 P=p                 csv_sort()                 with open('%s组%d栋%d楼.csv'%(W,K,P ),'a', newline='', encoding='utf-8-sig') as f:                     writer = csv.DictWriter(f, fieldnames=header,)  # 提前预览列名,当下面代码写入数据时,会将其一一对应。                     writer.writeheader()  # 写入列名                     writer.writerows(dicts)  # 写入数据                 print("{}组{}栋寝室{}楼数据已经写入成功!!!! ! !".format(W,K,P))1234567891011121314151617181920212223242526272829这个功能同样有几个坑,首先我们需要对数据设计好迭代for循环保存,并且利用OS模块继续自动的创建文件夹,最后对其数据进行命名,方便我们查看还有就是我们的CSV文件里面的编码是utf-8模式,但是Excel里面的编码不同,这个就会造成我们的中文数据形式的乱码问题。所以我们就去用了这个办法来解决了encoding='utf-8-sig'1下面我们来看看整体操作的演示效果代码升级版1.我们还可以参考一些办法,对这个表格数据进行自动制作,添加头部文件信息,当然我这里就不做演示了,你们可以自己去寻找不同的解决方法。2.我们还可以对数据表格进行网格线绘制,使其我们的表格更加美观,比如字体居中等3.编写一个自动打印的程序,链接到我们的电脑打印机,一键化打印这些数据,极大地提高了我们的效率。这些功能读者可以自己去实现,我这里就不做说明了,毕竟代码的涉及和项目不容易,哈哈哈哈!自动化办公,一键化处理,本来就是Python的强项,我们可以利用它的功能来解决我们学习生活的难题,最后我想致敬那些每天为了数据整理,疯狂的点击Excel的工作人员,毕竟这个东西头大,难搞,枯燥,乏味最后我想要说的是虽然设计项目程序比较的头疼,但是它可以移植,并且不断的升级,最后别人用1个小时,你只需要3秒钟运行查看即可!程序源码# -*- coding :  utf-8 -*-# @Time      :  2020/9/15 13:26# @author    :  王小王# @Software  :  PyCharm# @File      :  寝室数据分类.py-1.0版本# @CSDN      :  https://blog.csdn.net/weixin_47723732# 1.解析CSV海量数据,用字典保存在内存空间def csv_data():     global dormitory_data    import csv     dormitory_data = []     with open(r"寝室数据.csv", encoding='utf-8-sig') as file:#将你的CSV文件和该程序文件放在一个文件夹下面         f_csv = csv.reader(file)#读取文件里面的每一行数据,转换为列表赋值给新的变量         header = next(f_csv)#利用迭代的方法,直接取出表头行(标题行),更新f_csv的数据,去除了标题行         for row in f_csv:             data = {}             for index in range(7):                 data[header[index]] = row[index]             dormitory_data.append(data)# 分割数据,按照数据的特点def csv_sort():     global dicts     dicts=[];i = 0     dormitory_datas = dormitory_data.copy()#字典迭代删除迭代数据是一个坑,需要我们时刻更新数据库值     dormitory_datass= dormitory_data.copy()     for x in dormitory_datass:         b = []         for sort in dormitory_datass:             a_1 = sort["宿舍编号"]             b.append(a_1)         dicts.append(x)         dormitory_data.remove(x)         dormitory_datass=dormitory_data.copy()         if b[i][:3] != b[i+1][:3]:             break#保存数据,按照不同的分类def keep_data():     import csv    import os    import codecs    for w in range(65,73):         W=chr(w)         path = '%s栋寝室'%W      # 创建总的文件夹         if not os.path.exists(path):             os.mkdir(path)             os.chdir(path)         else:             os.chdir(path)         a = []         dict = dormitory_data[0]         for headers in dict.keys():  # 把字典的键取出来,注意不要使用sorted不然会导致键的顺序改变             a.append(headers)         header = a  # 把列名给提取出来,用列表形式呈现         for k in range(1,5):             K=k            for p in range(1,7):                 P=p                 csv_sort()                 with open('%s组%d栋%d楼.csv'%(W,K,P ),'a', newline='', encoding='utf-8-sig') as f:                     writer = csv.DictWriter(f, fieldnames=header,)  # 提前预览列名,当下面代码写入数据时,会将其一一对应。                     writer.writeheader()  # 写入列名                     writer.writerows(dicts)  # 写入数据                 print("{}组{}栋寝室{}楼数据已经写入成功!!!! ! !".format(W,K,P))def main():     csv_data()     keep_data()if __name__ == '__main__':     main()
总条数:2474 到第 页
上滑加载中