求速度,很紧急 日期的语法错误 在查询html正则表达式语法 '#2014/12/19 17:21:09' 中。

扫描下载客户端关于特种设备许可受理情况的公告(2014年第039批)
&>>&&>>&&>>&
关于特种设备许可受理情况的公告(2014年第039批)
发布时间:来源:省质监局字号:[
关于特种设备许可受理情况的公告&&&&根据《中华人民共和国特种设备安全法》、《特种设备行政许可实施办法(试行)》等有关规定,自至,浙江省质量技术监督局共受理了25家省内单位的特种设备设计、制造、安装改造修理许可和检验检测机构核准的申请。上述单位的名称、受理项目、受理日期和受理编号详见附件。 特此公告。序号申请单位单位地址申请项目受理编号受理日期备注 1
宁波港机厂宁波市镇海区蟹浦镇庙戴村329国道线起重机械制造(门座式起重机 B级: 固定式起重机 DG型35t及以下)浙质特许受字[号 换证
丽水市永固建筑设备有限公司浙江丽水市莲都区天宁街886号起重机械制造(升降机B级:施工升降机SC100-A型1t及以下、SC100/100-A型1t/1t及以下)浙质特许受字[号 增项
浙江虎力起重机械有限公司浙江省常山县球川镇红旗岗村起重机械制造(具体受理范围见附件)浙质特许受字[号 首次
宁波光力紧固件有限公司镇海区九龙湖镇西河村压力管道元件制造(B级紧固件:合金钢制M14以上螺柱、螺母)浙质特许受字[号 首次
温州市森鸿钢管有限公司温州市龙湾区永中街道建中街532-550号压力管道元件制造(B级无缝钢管:φ≤159mm,限GB/T 14976,奥氏体不锈钢 )浙质特许受字[号 换证
海宁虎霸重工有限公司浙江省嘉兴市海宁市尖山新区闻澜路28号起重机械制造(升降机B级:施工升降机SC200/200KZ型2.0t及以下、SC200/200KBN型2.0t及以下 )浙质特许受字[号 增项
上海昌懋电梯安装工程有限公司杭州分公司杭州市江干区秋涛北路176号8楼866房电梯修理(乘客电梯修理C级、载货电梯修理C级、自动扶梯修理C级、自动行人道修理C级)浙质特许受字[号 首次
浙江省方大标准信息有限公司浙江省杭州市环城北路305号耀江发展中心五层电梯安装、改造、修理(乘客电梯安装修理B级)浙质特许受字[号 增项
杭州西子起重机械有限公司杭州市江干区机场路172-25号起重机械制造(门式起重机B级:电动葫芦门式起重机MH型20t及以下)浙质特许受字[号 增项
宁海县岔路高坛液化气站浙江省宁波市宁海县岔路镇千秋桥头气瓶充装(液化石油气)浙质特许受字[号 换证
杭州浙起机械有限公司富阳市东洲工业功能区7号路9号起重机械制造(轻小型起重设备B级:钢丝绳电动葫芦ZHA型100t及以下)浙质特许受字[号 增项
温州市宏业气体有限公司浙江省温州市鹿城区轻工产业园区戍浦江路20号气瓶充装(氧气、二氧化碳 、液氧、液氮)浙质特许受字[号 首次
泰顺县鑫鸿液化气储配站(普通合伙)浙江省温州市泰顺县罗阳镇川山垟村豆腐岭气瓶充装(液化石油气)浙质特许受字[号 换证
建德市浙能天然气有限公司浙江省杭州市建德市新安江新安路18号气瓶充装(液化天然气)浙质特许受字[号 换证、名称变更
奥特朗博电梯有限公司浙江省义乌市上溪镇四通东路83号2楼电梯安装、改造、修理(乘客电梯、液压电梯安装改造修理A级,载货电梯、杂物电梯、自动扶梯安装改造修理B级,(分支机构限乘客电梯、液压电梯、载货电梯、杂物电梯、自动扶梯修理B级))浙质特许受字[号 换证
青田县船寮液化气有限公司浙江青田县船寮镇大洋村气瓶充装(液化石油气)浙质特许受字[号 换证
宁波仁捷电梯设备工程有限公司宁波市鄞州区四明东路128号电梯修理(乘客电梯、载货电梯修理B级;杂物电梯、自动扶梯、自动人行道修理C级)浙质特许受字[号 换证
浙江正工阀门有限公司永嘉县瓯北镇东瓯工业区压力管道元件制造(B2级阀门:球阀PN≤4.0MPa,DN≤400mm)浙质特许受字[号 换证、名称变更
宁波凌云电梯有限公司浙江省象山县丹西街道白鹤路149号电梯安装、修理(乘客电梯、载货电梯、杂物电梯、自动扶梯、自动人行道安装、修理C级)浙质特许受字[号 地址变更(无需评审)
浙江冠正阀门股份有限公司浙江省永嘉县瓯北镇堡一工业区压力管道元件制造(B1、B2级阀门:闸阀PN≤6.4MPa、DN≤100mm,PN≤4.0MPa、DN≤400mm;截止阀PN≤6.4MPa、DN≤100mm,PN≤4.0MPa、DN≤400mm;止回阀PN≤6.4MPa、DN≤100mm,PN≤4.0MPa、DN≤300mm;球阀PN≤6.4MPa、DN≤100mm,PN≤4.0MPa、DN≤400mm;蝶阀PN≤2.5MPa、DN≤100mm,PN≤1.6MPa、DN≤500mm)浙质特许受字[号 名称变更(无需评审)
浙江华鑫起重机械有限公司浙江松阳县西屏街道御景园2幢6号起重机械制造(桥式起重机B级:通用桥式起重机QD型50 t及以下、电动葫芦桥式起重机LH型32 t及以下、电动单梁起重机LD型16 t及以下、门式起重机B 级: 电动葫芦门式起重机MH型16 t及以下
)浙质特许受字[号 首次
浙江兴土桥梁专用装备制造有限公司嘉兴市秀洲区加创路1509号中国节能嘉兴产业园14#研发楼南楼101-2室起重机械安装、改造、修理(桥式起重机A级安装修理,门式起重机A级安装修理改造)浙质特许受字[号 首次
温州大和阀门有限公司永嘉县东瓯街道堡一村文化路大和阀门压力管道元件制造(B2级阀门:闸阀PN≤4.0MPa、DN≤200mm;截止阀PN≤4.0MPa、DN≤200mm)浙质特许受字[号 地址变更
永嘉县正旭阀门有限公司永嘉县东瓯街道东瓯工业区压力管道元件制造(B1、B2级阀门:节流阀PN=6.4MPa、DN<200mm,PN<6.4MPa、DN≤400mm)浙质特许受字[号 首次
浙江利水铜业有限公司浙江省玉环县珠港镇城关白岩压力管道元件制造(B2级阀门:截止阀PN≤2.5MPa、DN≤100mm,球阀PN≤2.5MPa、DN≤100mm,闸阀PN≤2.5MPa、DN≤100mm)浙质特许受字[号 首次
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 二〇一四年十月十三日网站标题:
Neil Strauss' Stylelife Academy
网站简介:
网站关键字:
Pick,Up,Artist,,PUA,,Neil,Strauss,,The,G
更多查询:
备案情况:
网站综合价值评估简报
该网站创建于日,已有10年61天的历史,ALEXA排名348,120位,谷歌对该网站评分为,搜狗对该网站评分为,百度为该网站评分为,百度搜索结果前100名关键字约为个0 个,预测该网站每天约有较少IP,其中电脑端 -
IP,移动端 -
[正确]---title标签设置合理。
keywords:
[正确]---keywords标签设置合理。
description:
[警示]---description标签设置不规范,或者为空。
javascript:
[建议]---Javascript脚本建议写到.js文件中,有利于搜索引擎抓取
style样式:
[建议]---CSS样式建议写到.css文件中以缩减代码的繁琐度有利于搜索引擎抓取
flash/object:
[建议]---flash/object加上相关说明文字,有利于搜索引擎识别内容
图片Alt信息:
[警示]---存在没有alt信息的img标签,加入这项信息可使您网页上的图片更容易被用户检索到
frame信息:
[建议]---frame/frameset/iframe标签会导致spider的抓取困难,建议您尽量不要使用
[建议]---百度建议url的最长长度不超过255byte
html标签:
[正确]---html标签设置合理。
百度快照:
[警告]---百度快照较旧,请注意加强SEO优化。
百度当日收录:
[警告]---百度当日没有新收录,请注意加强SEO优化。
Alexa排名:
348,120 &&&
日IP估值:
日PV估值:
百度权重:
搜狗评级:
百度当日收录
百度本周收录
百度本月收录
&&网站历史收录&&&&&
百度索引量
托管地址:
United States Newark
所在地址:
Whois服务:
域名状态:
clientDeleteProhibited&&clientTransferProhibited&&clientUpdateProhibited
注册时间:
到期时间:
注册邮箱:
@monikerprivacy.net
域名年龄:
Moniker Whois Server Version 2.0
The Data in Moniker's WHOIS database
is provided for information purposes only, and is
designed to assist persons in obtaining information
related to domain name registration records.
Moniker does not guarantee its accuracy.
By submitting a WHOIS query, you agree that you
will use this Data only for lawful purposes and
that, under no circumstances will you use this Data
to: (1) allow, enable, or otherwise support the
transmission of mass unsolicited, commercial
advertising or solicitations via e-mail (spam),
telephone, or
(2) enable high volume, automated, electronic
processes that apply to Moniker (or its
systems). Moniker reserves the right
to modify these terms at any time.
By submitting
this query, you agree to abide by this policy.
The compilation, repackaging, dissemination or
other use of this Data is expressly
prohibited without the prior written consent
of Moniker.
Domain Name:
Registrar: MONIKER
Registrant [305032]:
Moniker Privacy @monikerprivacy.net
Moniker Privacy Services
1800 SW 1st Avenue
Administrative Contact [305032]:
Moniker Privacy @monikerprivacy.net
Moniker Privacy Services
1800 SW 1st Avenue
Phone: +1.
Billing Contact [305032]:
Moniker Privacy @monikerprivacy.net
Moniker Privacy Services
1800 SW 1st Avenue
Phone: +1.
Technical Contact [305032]:
Moniker Privacy @monikerprivacy.net
Moniker Privacy Services
1800 SW 1st Avenue
Phone: +1.
Domain servers in listed order:
NS1.LNHI.NET
NS2.LNHI.NET
Record created on:
14:17:00.0
Database last updated on:
12:00:32.913
Domain Expires on:
14:17:00.0
点评:你的是很有发展潜力的站,加油!
您的帐号尚未登录,请
&&网站缩略图
&&网站头文件(header信息)
HTTP/1.1 301 Moved PermanentlyDate: Tue, 16 Dec :13 GMTServer: Apache/2.0.52 (Red Hat)Location: /Content-Type: text/ charset=iso-8859-1
&&相关查询
Copyright 2014, Web3389. All rights reserved.Python 程序员必知必会的开发者工具
Python已经演化出了一个广泛的生态系统,该生态系统能够让Python程序员的生活变得更加简单,减少他们重复造轮的工作。同样的理念也适用于工具开发者的工作,即便他们开发出的工具并没有出现在最终的程序中。本文将介绍Python程序员必知必会的开发者工具。对于开发者来说,最实用的帮助莫过于帮助他们编写代码文档了。模块可以根据源代码中的docstrings为任何可导入模块生成格式良好的文档。Python包含了两个测试框架来自动测试代码以及验证代码的正确性:1)模块,该模块可以从源代码或独立文件的例子中抽取出测试用例。2)模块,该模块是一个全功能的自动化测试框架,该框架提供了对测试准备(test fixtures), 预定义测试集(predefined test suite)以及测试发现(test discovery)的支持。模块可以监控Python执行程序的方式,同时生成一个报表来显示程序的每一行执行的次数。这些信息可以用来发现未被自动化测试集所覆盖的程序执行路径,也可以用来研究程序调用图,进而发现模块之间的依赖关系。编写并执行测试可以发现绝大多数程序中的问题,Python使得debug工作变得更加简单,这是因为在大部分情况下,Python都能够将未被处理的错误打印到控制台中,我们称这些错误信息为traceback。如果程序不是在文本控制台中运行的,traceback也能够将错误信息输出到日志文件或是消息对话框中。当标准的traceback无法提供足够的信息时,可以使用cgitb 模块来查看各级栈和源代码上下文中的详细信息,比如局部变量。模块还能够将这些跟踪信息以HTML的形式输出,用来报告web应用中的错误。一旦发现了问题出在哪里后,就需要使用到交互式调试器进入到代码中进行调试工作了,模块能够很好地胜任这项工作。该模块可以显示出程序在错误产生时的执行路径,同时可以动态地调整对象和代码进行调试。当程序通过测试并调试后,下一步就是要将注意力放到性能上了。开发者可以使用以及模块来测试程序的速度,找出程序中到底是哪里很慢,进而对这部分代码独立出来进行调优的工作。Python程序是通过解释器执行的,解释器的输入是原有程序的字节码编译版本。这个字节码编译版本可以在程序执行时动态地生成,也可以在程序打包的时候就生成。模块可以处理程序打包的事宜,它暴露出了打包相关的接口,该接口能够被安装程序和打包工具用来生成包含模块字节码的文件。同时,在开发环境中,compileall模块也可以用来验证源文件是否包含了语法错误。在源代码级别,模块提供了一个类查看器,方便文本编辑器或是其他程序对Python程序中有意思的字符进行扫描,比如函数或者是类。在提供了类查看器以后,就无需引入代码,这样就避免了潜在的副作用影响。文档字符串与doctest模块如果函数,类或者是模块的第一行是一个字符串,那么这个字符串就是一个文档字符串。可以认为包含文档字符串是一个良好的编程习惯,这是因为这些字符串可以给Python程序开发工具提供一些信息。比如,help()命令能够检测文档字符串,Python相关的IDE也能够进行检测文档字符串的工作。由于程序员倾向于在交互式shell中查看文档字符串,所以最好将这些字符串写的简短一些。例如#&mult.py
class&Test:
&&&&&&&&a=Test(5)
&&&&&&&&a.multiply_by_2()
&&&&def&__init__(self,&number):
&&&&&&&&self._number=number
&&&&def&multiply_by_2(self):
&&&&&&&&return&self._number*2在编写文档时,一个常见的问题就是如何保持文档和实际代码的同步。例如,程序员也许会修改函数的实现,但是却忘记了更新文档。针对这个问题,我们可以使用doctest模块。doctest模块收集文档字符串,并对它们进行扫描,然后将它们作为测试进行执行。为了使用doctest模块,我们通常会新建一个用于测试的独立的模块。例如,如果前面的例子Test class包含在文件mult.py中,那么,你应该新建一个testmult.py文件用来测试,如下所示:#&testmult.py
import&mult,&doctest
doctest.testmod(mult,&verbose=True)
#&&&&&a=Test(5)
#&Expecting&nothing
#&&&&&a.multiply_by_2()
#&Expecting:
#&3&items&had&no&tests:
#&&&&&mult
#&&&&&mult.Test.__init__
#&&&&&mult.Test.multiply_by_2
#&1&items&passed&all&tests:
#&&&&2&tests&in&mult.Test
#&2&tests&in&4&items.
#&2&passed&and&0&failed.
#&Test&passed.在这段代码中,doctest.testmod(module)会执行特定模块的测试,并且返回测试失败的个数以及测试的总数目。如果所有的测试都通过了,那么不会产生任何输出。否则的话,你将会看到一个失败报告,用来显示期望值和实际值之间的差别。如果你想看到测试的详细输出,你可以使用testmod(module, verbose=True).如果不想新建一个单独的测试文件的话,那么另一种选择就是在文件末尾包含相应的测试代码:if&__name__&==&'__main__':
&&&&import&doctest
&&&&doctest.testmod()如果想执行这类测试的话,我们可以通过-m选项调用doctest模块。通常来讲,当执行测试的时候没有任何的输出。如果想查看详细信息的话,可以加上-v选项。$&python&-m&doctest&-v&mult.py单元测试与unittest模块如果想更加彻底地对程序进行测试,我们可以使用unittest模块。通过单元测试,开发者可以为构成程序的每一个元素(例如,独立的函数,方法,类以及模块)编写一系列独立的测试用例。当测试更大的程序时,这些测试就可以作为基石来验证程序的正确性。当我们的程序变得越来越大的时候,对不同构件的单元测试就可以组合起来成为更大的测试框架以及测试工具。这能够极大地简化软件测试的工作,为找到并解决软件问题提供了便利。#&splitter.py
import&unittest
def&split(line,&types=None,&delimiter=None):
&&&&&&&Splits&a&line&of&text&and&optionally&performs&type&conversion.
&&&&fields&=&line.split(delimiter)
&&&&if&types:
&&&&&&&&fields&=&[&ty(val)&for&ty,val&in&zip(types,fields)&]
&&&&return&fields
class&TestSplitFunction(unittest.TestCase):
&&&&def&setUp(self):
&&&&&&&&#&Perform&set&up&actions&(if&any)
&&&&&&&&pass
&&&&def&tearDown(self):
&&&&&&&&#&Perform&clean-up&actions&(if&any)
&&&&&&&&pass
&&&&def&testsimplestring(self):
&&&&&&&&r&=&split('GOOG&100&490.50')
&&&&&&&&self.assertEqual(r,['GOOG','100','490.50'])
&&&&def&testtypeconvert(self):
&&&&&&&&r&=&split('GOOG&100&490.50',[str,&int,&float])
&&&&&&&&self.assertEqual(r,['GOOG',&100,&490.5])
&&&&def&testdelimiter(self):
&&&&&&&&r&=&split('GOOG,100,490.50',delimiter=',')
&&&&&&&&self.assertEqual(r,['GOOG','100','490.50'])
#&Run&the&unittests
if&__name__&==&'__main__':
&&&&unittest.main()
#----------------------------------------------------------------------
#Ran&3&tests&in&0.001s
#OK在使用单元测试时,我们需要定义一个继承自unittest.TestCase的类。在这个类里面,每一个测试都以方法的形式进行定义,并都以test打头进行命名——例如,’testsimplestring‘,’testtypeconvert‘以及类似的命名方式(有必要强调一下,只要方法名以test打头,那么无论怎么命名都是可以的)。在每个测试中,断言可以用来对不同的条件进行检查。实际的例子:假如你在程序里有一个方法,这个方法的输出指向标准输出(sys.stdout)。这通常意味着是往屏幕上输出文本信息。如果你想对你的代码进行测试来证明这一点,只要给出相应的输入,那么对应的输出就会被显示出来。#&url.py
def&urlprint(protocol,&host,&domain):
&&&&url&=&'{}://{}.{}'.format(protocol,&host,&domain)
&&&&print(url)内置的print函数在默认情况下会往sys.stdout发送输出。为了测试输出已经实际到达,你可以使用一个替身对象对其进行模拟,并且对程序的期望值进行断言。unittest.mock模块中的patch()方法可以只在运行测试的上下文中才替换对象,在测试完成后就立刻返回对象原始的状态。下面是urlprint()方法的测试代码:#urltest.py
from&io&import&StringIO
from&unittest&import&TestCase
from&unittest.mock&import&patch
import&url
class&TestURLPrint(TestCase):
&&&&def&test_url_gets_to_stdout(self):
&&&&&&&&protocol&=&'http'
&&&&&&&&host&=&'www'
&&&&&&&&domain&=&&#'
&&&&&&&&expected_url&=&'{}://{}.{}\n'.format(protocol,&host,&domain)
&&&&&&&&with&patch('sys.stdout',&new=StringIO())&as&fake_out:
&&&&&&&&&&&&url.urlprint(protocol,&host,&domain)
&&&&&&&&&&&&self.assertEqual(fake_out.getvalue(),&expected_url)urlprint()函数有三个参数,测试代码首先给每个参数赋了一个假值。变量expected_url包含了期望的输出字符串。为了能够执行测试,我们使用了unittest.mock.patch()方法作为上下文管理器,把标准输出sys.stdout替换为了StringIO对象,这样发送的标准输出的内容就会被StringIO对象所接收。变量fake_out就是在这一过程中所创建出的模拟对象,该对象能够在with所处的代码块中所使用,来进行一系列的测试检查。当with语句完成时,patch方法能够将所有的东西都复原到测试执行之前的状态,就好像测试没有执行一样,而这无需任何额外的工作。但对于某些Python的C扩展来讲,这个例子却显得毫无意义,这是因为这些C扩展程序绕过了sys.stdout的设置,直接将输出发送到了标准输出上。这个例子仅适用于纯Python代码的程序(如果你想捕获到类似C扩展的输入输出,那么你可以通过打开一个临时文件然后将标准输出重定向到该文件的技巧来进行实现)。Python调试器与pdb模块Python在pdb模块中包含了一个简单的基于命令行的调试器。pdb模块支持事后调试(post-mortem debugging),栈帧探查(inspection of stack frames),断点(breakpoints),单步调试(single-stepping of source lines)以及代码审查(code evaluation)。有都能够在程序中调用调试器,或是在交互式的Python终端中进行调试工作。在所有启动调试器的函数中,函数set_trace()也许是最简易实用的了。如果在复杂程序中发现了问题,可以在代码中插入set_trace()函数,并运行程序。当执行到set_trace()函数时,这就会暂停程序的执行并直接跳转到调试器中,这时候你就可以大展手脚开始检查运行时环境了。当退出调试器时,调试器会自动恢复程序的执行。假设你的程序有问题,你想找到一个简单的方法来对它进行调试。如果你的程序崩溃时报了一个异常错误,那么你可以用python3 -i someprogram.py这个命令来运行你的程序,这能够很好地发现问题所在。-i选项表明只要程序终结就立即启动一个交互式shell。在这个交互式shell中,你就可以很好地探查到底发生了什么导致程序的错误。例如,如果你有以下代码:def&function(n):
&&&&return&n&+&10
function(&Hello&)如果使用python3 -i 命令运行程序就会产生如下输出:python3&-i&sample.py
Traceback&(most&recent&call&last):
&&File&&sample.py&,&line&4,&in&&module&
&&&&function(&Hello&)
&&File&&sample.py&,&line&2,&in&function
&&&&return&n&+&10
TypeError:&Can't&convert&'int'&object&to&str&implicitly
&&&&function(20)
&&&如果你没有发现什么明显的错误,那么你可以进一步地启动Python调试器。例如:&&&&import&pdb
&&&&pdb.pm()
&&sample.py(4)func()
-&&return&n&+&10
sample.py(6)&module&()
-&&func('Hello')
&&sample.py(4)func()
-&&return&n&+&10
(Pdb)&print&n
'Hello'
&&&如果你的代码身处的环境很难启动一个交互式shell的话(比如在服务器环境下),你可以增加错误处理的代码,并自己输出跟踪信息。例如:import&traceback
import&sys
&&&&func(arg)
&&&&print('****&AN&ERROR&OCCURRED&****')
&&&&traceback.print_exc(file=sys.stderr)如果你的程序并没有崩溃,而是说程序的行为与你的预期表现的不一致,那么你可以尝试在一些可能出错的地方加入print()函数。如果你打算采用这种方案的话,那么还有些相关的技巧值得探究。首先,函数traceback.print_stack()能够在被执行时立即打印出程序中栈的跟踪信息。例如:&&&&def&sample(n):
...&&&&&if&n&&&0:
...&&&&&&&&&sample(n-1)
...&&&&&else:
...&&&&&&&&&traceback.print_stack(file=sys.stderr)
&&&&sample(5)
File&&&stdin&&,&line&1,&in&&module&
File&&&stdin&&,&line&3,&in&sample
File&&&stdin&&,&line&3,&in&sample
File&&&stdin&&,&line&3,&in&sample
File&&&stdin&&,&line&3,&in&sample
File&&&stdin&&,&line&3,&in&sample
File&&&stdin&&,&line&5,&in&sample
&&&另外,你可以在程序中任意一处使用pdb.set_trace()手动地启动调试器,就像这样:import&pdb
def&func(arg):
&&&&pdb.set_trace()
&&&&...在深入解析大型程序的时候,这是一个非常实用的技巧,这样操作能够清楚地了解程序的控制流或是函数的参数。比如,一旦调试器启动了之后,你就可以使用print或者w命令来查看变量,来了解栈的跟踪信息。在进行软件调试时,千万不要让事情变得很复杂。有时候仅仅需要知道程序的跟踪信息就能够解决大部分的简单错误(比如,实际的错误总是显示在跟踪信息的最后一行)。在实际的开发过程中,将print()函数插入到代码中也能够很方便地显示调试信息(只需要记得在调试完以后将print语句删除掉就行了)。调试器的通用用法是在崩溃的函数中探查变量的值,知道如何在程序崩溃以后再进入到调试器中就显得非常实用。在程序的控制流不是那么清楚的情况下,你可以插入pdb.set_trace()语句来理清复杂程序的思路。本质上,程序会一直执行直到遇到set_trace()调用,之后程序就会立刻跳转进入到调试器中。在调试器里,你就可以进行更多的尝试。如果你正在使用Python的IDE,那么IDE通常会提供基于pdb的调试接口,你可以查阅IDE的相关文档来获取更多的信息。下面是一些Python调试器入门的资源列表:阅读Steve Ferb的文章 观看Eric Holscher的截图 阅读Ayman Hourieh的文章 阅读 阅读Karen Tracey的一书中的第九章——When You Don’t Even Know What to Log: Using Debuggers程序分析profile模块和cProfile模块可以用来分析程序。它们的工作原理都一样,唯一的区别是,cProfile模块是以C扩展的方式实现的,如此一来运行的速度也快了很多,也显得比较流行。这两个模块都可以用来收集覆盖信息(比如,有多少函数被执行了),也能够收集性能数据。对一个程序进行分析的最简单的方法就是运行这个命令:%&python&-m&cProfile&someprogram.py此外,也可以使用profile模块中的run函数:run(command&[,&filename])该函数会使用exec语句执行command中的内容。filename是可选的文件保存名,如果没有filename的话,该命令的输出会直接发送到标准输出上。下面是分析器执行完成时的输出报告:126&function&calls&(6&primitive&calls)&in&5.130&CPU&seconds
Ordered&by:&standard&name
ncalls&tottime&percall&cumtime&percall&filename:lineno(function)
1&0.030&0.030&5.070&5.070&&string&:1(?)
121/1&5.020&0.041&5.020&5.020&book.py:11(process)
1&0.020&0.020&5.040&5.040&book.py:5(?)
2&0.000&0.000&0.000&0.000&exceptions.py:101(_&_init_&_)
1&0.060&0.060&5.130&5.130&profile:0(execfile('book.py'))
0&0.000&0.000&profile:0(profiler)当输出中的第一列包含了两个数字时(比如,121/1),后者是元调用(primitive call)的次数,前者是实际调用的次数(译者注:只有在递归情况下,实际调用的次数才会大于元调用的次数,其他情况下两者都相等)。对于绝大部分的应用程序来讲使用该模块所产生的的分析报告就已经足够了,比如,你只是想简单地看一下你的程序花费了多少时间。然后,如果你还想将这些数据保存下来,并在将来对其进行分析,你可以使用pstats模块。假设你想知道你的程序究竟在哪里花费了多少时间。如果你只是想简单地给你的整个程序计时的话,使用Unix中的time命令就已经完全能够应付了。例如:bash&%&time&python3&someprogram.py
real&0m13.937s
user&0m12.162s
sys&0m0.098s
bash&%通常来讲,分析代码的程度会介于这两个极端之间。比如,你可能已经知道你的代码会在一些特定的函数中花的时间特别多。针对这类特定函数的分析,我们可以使用修饰器decorator,例如:import&time
from&functools&import&wraps
def&timethis(func):
&&&&@wraps(func)
&&&&def&wrapper(*args,&**kwargs):
&&&&&&&&start&=&time.perf_counter()
&&&&&&&&r&=&func(*args,&**kwargs)
&&&&&&&&end&=&time.perf_counter()
&&&&&&&&print('{}.{}&:&{}'.format(func.__module__,&func.__name__,&end&-&start))
&&&&&&&&return&r
&&&&return&wrapper使用decorator的方式很简单,你只需要把它放在你想要分析的函数的定义前面就可以了。例如:&&&&@timethis
...&def&countdown(n):
...&&&&&while&n&&&0:
...&&&&&&&&&n&-=&1
&&&&countdown()
__main__.countdown&:&0.752
&&&如果想要分析一个语句块的话,你可以定义一个上下文管理器(context manager)。例如:import&time
from&contextlib&import&contextmanager
@contextmanager
def&timeblock(label):
&&&&start&=&time.perf_counter()
&&&&&&&&yield
&&&&finally:
&&&&&&&&end&=&time.perf_counter()
&&&&&&&&print('{}&:&{}'.format(label,&end&-&start))接下来是如何使用上下文管理器的例子:&&&&with&timeblock('counting'):
...&&&&&n&=&
...&&&&&while&n&&&0:
...&&&&&&&&&n&-=&1
counting&:&1.6455
&&&如果想研究一小段代码的性能的话,timeit模块会非常有用。例如:&&&&from&timeit&import&timeit
&&&&timeit('math.sqrt(2)',&'import&math')
&&&&timeit('sqrt(2)',&'from&math&import&sqrt')
&&&timeit的工作原理是,将第一个参数中的语句执行100万次,然后计算所花费的时间。第二个参数指定了一些测试之前需要做的环境准备工作。如果你需要改变迭代的次数,可以附加一个number参数,就像这样:&&&&timeit('math.sqrt(2)',&'import&math',&number=)
&&&&timeit('sqrt(2)',&'from&math&import&sqrt',&number=)
&&&当进行性能评估的时候,要牢记任何得出的结果只是一个估算值。函数time.perf_counter()能够在任一平台提供最高精度的计时器。然而,它也只是记录了自然时间,记录自然时间会被很多其他因素影响,比如,计算机的负载。如果你对处理时间而非自然时间感兴趣的话,你可以使用time.process_time()。例如:import&time
from&functools&import&wraps
def&timethis(func):
&&&&@wraps(func)
&&&&def&wrapper(*args,&**kwargs):
&&&&&&&&start&=&time.process_time()
&&&&&&&&r&=&func(*args,&**kwargs)
&&&&&&&&end&=&time.process_time()
&&&&&&&&print('{}.{}&:&{}'.format(func.__module__,&func.__name__,&end&-&start))
&&&&&&&&return&r
&&&&return&wrapper最后也是相当重要的就是,如果你想做一个详细的性能评估的话,你最好查阅time,timeit以及其他相关模块的文档,这样你才能够对平台相关的不同之处有所了解。profile模块中最基础的东西就是run()函数了。该函数会把一个语句字符串作为参数,然后在执行语句时生成所花费的时间报告。import&profile
def&fib(n):
&&&&#&from&literateprograms.org
&&&&#&http://bit.ly/hlOQ5m
&&&&if&n&==&0:
&&&&&&&&return&0
&&&&elif&n&==&1:
&&&&&&&&return&1
&&&&&&&&return&fib(n-1)&+&fib(n-2)
def&fib_seq(n):
&&&&seq&=&[]
&&&&if&n&&&0:
&&&&&&&&seq.extend(fib_seq(n-1))
&&&&seq.append(fib(n))
&&&&return&seq
profile.run('print(fib_seq(20));&print')性能优化当你的程序运行地很慢的时候,你就会想去提升它的运行速度,但是你又不想去借用一些复杂方案的帮助,比如使用C扩展或是just-in-time(JIT)编译器。那么这时候应该怎么办呢?要牢记性能优化的第一要义就是“不要为了优化而去优化,应该在我们开始写代码之前就想好应该怎样编写高性能的代码”。第二要义就是“优化一定要抓住重点,找到程序中最重要的地方去优化,而不要去优化那些不重要的部分”。通常来讲,你会发现你的程序在某些热点上花费了很多时间,比如内部数据的循环处理。一旦你发现了问题所在,你就可以对症下药,让你的程序更快地执行。使用函数许多开发者刚开始的时候会将Python作为一个编写简单脚本的工具。当编写脚本的时候,很容易就会写一些没有结构的代码出来。例如:import&sys
import&csv
with&open(sys.argv[1])&as&f:
&&&&for&row&in&csv.reader(f):
&&&&#&Some&kind&of&processing但是,却很少有人知道,定义在全局范围内的代码要比定义在函数中的代码执行地慢。他们之间速度的差别是因为局部变量与全局变量不同的实现所引起的(局部变量的操作要比全局变量来得快)。所以,如果你想要让程序更快地运行,那么你可以简单地将代码放在一个函数中,就像这样:import&sys
import&csv
def&main(filename):
&&&&with&open(filename)&as&f:
&&&&&&&&for&row&in&csv.reader(f):
&&&&&&&&&&&&#&Some&kind&of&processing
&&&&&&&&&&&&...
main(sys.argv[1])这样操作以后,处理速度会有提升,但是这个提升的程度依赖于程序的复杂性。根据经验来讲,通常都会提升15%到30%之间。选择性地减少属性的访问当使用点(.)操作符去访问属性时都会带来一定的消耗。本质上来讲,这会触发一些特殊方法的执行,比如__getattribute__()和__getattr__(),这通常都会导致去内存中字典数据的查询。你可以通过两种方式来避免属性的访问,第一种是使用from module import name的方式。第二种是将对象的方法名保存下来,在调用时直接使用。为了解释地更加清楚,我们来看一个例子:import&math
def&compute_roots(nums):
&&&&result&=&[]
&&&&for&n&in&nums:
&&&&&&&&result.append(math.sqrt(n))
&&&&return&result
nums&=&range(1000000)
for&n&in&range(100):
&&&&r&=&compute_roots(nums)上面的代码在我的计算机上运行大概需要40秒的时间。现在我们把上面代码中的compute_roots()函数改写一下:from&math&import&sqrt
def&compute_roots(nums):
&&&&result&=&[]
&&&&result_append&=&result.append
&&&&for&n&in&nums:
&&&&&&&&result_append(sqrt(n))
&&&&return&result
nums&=&range(1000000)
for&n&in&range(100):
&&&&r&=&compute_roots(nums)这个版本的代码执行一下大概需要29秒。这两个版本的代码唯一的不同之处在于后面一个版本减少了对属性的访问。在后面一段代码中,我们使用了sqrt()方法,而非math.sqrt()。result.append()函数也被存进了一个局部变量result_append中,然后在循环当中重复使用。然而,有必要强调一点是说,这种方式的优化仅仅针对经常运行的代码有效,比如循环。由此可见,优化仅仅在那些小心挑选出来的地方才会真正得到体现。理解变量的局部性上面已经讲过,局部变量的操作比全局变量来得快。对于经常要访问的变量来说,最好把他们保存成局部变量。例如,考虑刚才已经讨论过的compute_roots()函数修改版:import&math
def&compute_roots(nums):
&&&&sqrt&=&math.sqrt
&&&&result&=&[]
&&&&result_append&=&result.append
&&&&for&n&in&nums:
&&&&&&&&result_append(sqrt(n))
&&&&return&result在这个版本中,sqrt函数被一个局部变量所替代。如果你执行这段代码的话,大概需要25秒就执行完了(前一个版本需要29秒)。 这次速度的提升是因为sqrt局部变量的查询比sqrt函数的全局查询来得稍快。局部性原来同样适用于类的参数。通常来讲,使用self.name要比直接访问局部变量来得慢。在内部循环中,我们可以将经常要访问的属性保存为一个局部变量。例如:#Slower
class&SomeClass:
&&&&def&method(self):
&&&&&&&&for&x&in&s:
&&&&&&&&&&&&op(self.value)
class&SomeClass:
def&method(self):
&&&&value&=&self.value
&&&&for&x&in&s:
&&&&&&&&op(value)避免不必要的抽象任何时候当你想给你的代码添加其他处理逻辑,比如添加装饰器,属性或是描述符,你都是在拖慢你的程序。例如,考虑这样一个类:class&A:
&&&&def&__init__(self,&x,&y):
&&&&&&&&self.x&=&x
&&&&&&&&self.y&=&y
&&&&@property
&&&&def&y(self):
&&&&&&&&return&self._y
&&&&@y.setter
&&&&def&y(self,&value):
&&&&&&&&self._y&=&value现在,让我们简单地测试一下:&&&&from&timeit&import&timeit
&&&&a&=&A(1,2)
&&&&timeit('a.x',&'from&__main__&import&a')
&&&&timeit('a.y',&'from&__main__&import&a')
&&&正如你所看到的,我们访问属性y比访问简单属性x不是慢了一点点,整整慢了4.5倍之多。如果你在乎性能的话,你就很有必要问一下你自己,对y的那些额外的定义是否都是必要的了。如果不是的话,那么你应该把那些额外的定义删掉,用一个简单的属性就够了。如果只是因为在其他语言里面经常使用getter和setter函数的话,你完全没有必要在Python中也使用相同的编码风格。使用内置的容器内置的数据结构,例如字符串(string),元组(tuple),列表(list),集合(set)以及字典(dict)都是用C语言实现的,正是因为采用了C来实现,所以它们的性能表现也很好。如果你倾向于使用你自己的数据结构作为替代的话(例如,链表,平衡树或是其他数据结构),想达到内置数据结构的速度的话是非常困难的。因此,你应该尽可能地使用内置的数据结构。避免不必要的数据结构或是数据拷贝有时候程序员会有点儿走神,在不该用到数据结构的地方去用数据结构。例如,有人可能会写这样的的代码:values&=&[x&for&x&in&sequence]
squares&=&[x*x&for&x&in&values]也许他这么写是为了先得到一个列表,然后再在这个列表上进行一些操作。但是第一个列表是完全没有必要写在这里的。我们可以简单地把代码写成这样就行了:squares&=&[x*x&for&x&in&sequence]有鉴于此,你要小心那些偏执程序员所写的代码了,这些程序员对Python的值共享机制非常偏执。函数copy.deepcopy()的滥用也许是一个信号,表明该代码是由菜鸟或者是不相信Python内存模型的人所编写的。在这样的代码里,减少copy的使用也许会比较安全。在优化之前,很有必要先详细了解一下你所要使用的算法。如果你能够将算法的复杂度从O(n^2)降为O(n log n)的话,程序的性能将得到极大的提高。如果你已经打算进行优化工作了,那就很有必要全局地考虑一下。普适的原则就是,不要想去优化程序的每一个部分,这是因为优化工作会让代码变得晦涩难懂。相反,你应该把注意力集中在已知的性能瓶颈处,例如内部循环。你需要谨慎地对待微优化(micro-optimization)的结果。例如,考虑下面两种创建字典结构的方式:a&=&{
'name'&:&'AAPL',
'shares'&:&100,
'price'&:&534.22
b&=&dict(name='AAPL',&shares=100,&price=534.22)后面那一种方式打字打的更少一些(因为你不必将key的名字用双引号括起来)。然而当你将这两种编码方式进行性能对比时,你会发现使用dict()函数的方式比另一种慢了3倍之多!知道了这一点以后,你也许会倾向于扫描你的代码,把任何出现dict()的地方替换为另一种冗余的写法。然而,一个聪明的程序员绝对不会这么做,他只会将注意力放在值得关注的地方,比如在循环上。在其他地方,速度的差异并不是最重要的。但是,如果你想让你的程序性能有质的飞跃的话,你可以去研究下基于JIT技术的工具。比如,PyPy项目,该项目是Python解释器的另一种实现,它能够分析程序的执行并为经常执行的代码生成机器码,有时它甚至能够让Python程序的速度提升一个数量级,达到(甚至超过)C语言编写的代码的速度。但是不幸的是,在本文正在写的时候,PyPy还没有完全支持Python 3。所以,我们还是在将来再来看它到底会发展的怎么样。基于JIT技术的还有Numba项目。该项目实现的是一个动态的编译器,你可以将你想要优化的Python函数以注解的方式进行标记,然后这些代码就会在LLVM的帮助下被编译成机器码。该项目也能够带来极大的性能上的提升。然而,就像PyPy一样,该项目对Python 3的支持还只是实验性的。最后,但是也很重要的是,请牢记John Ousterhout(译者注:Tcl和Tk的发明者,现为斯坦福大学计算机系的教授)说过的话“将不工作的东西变成能够工作的,这才是最大的性能提升”。在你需要优化前不要过分地考虑程序的优化工作。程序的正确性通常来讲都比程序的性能要来的重要。原文链接: &&&翻译:
- 译文链接:
Python 的详细介绍:
Python 的下载地址:
想通过手机客户端(支持 Android、iPhone 和 Windows Phone)访问开源中国:
旧一篇: 12个月前
新一篇: 12个月前
相关讨论话题
你也许会喜欢
2楼:蓝桥书生
3楼:huangjacky
4楼:guoyh
5楼:temgy1986 来自
好东西,收藏之。
6楼:ARKII 来自
7楼:王铁锤
8楼:林夕_信仰
10楼:老学生
不错的文档
11楼:johnchain_li
12楼:xc_xiechuang
13楼:yuris_115
非常有助于调试啊
14楼:喵心雨
15楼:Jiangxinxin
与内容无关的评论将被删除,严重者禁用帐号
本周热点资讯
本站最新资讯}

我要回帖

更多关于 正则表达式语法 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信