Python编程(共4篇)
Python编程 篇1
1 网络编程简介
1.1 基本概念
(1)Socket
Socket的英文原义是“孔”或“插座”。Socket非常类似于电话插座。以一个国家级电话网为例,电话的通话双方相当于相互通信的2个进程,区号是它的网络地址;区内一个单位的交换机相当于一台主机,主机分配给每个用户的局内号码相当于Socket号。任何用户在通话之前,首先要占有一部电话机,相当于申请一个Socket;同时要知道对方的号码,相当于对方有一个固定的Socket。然后向对方拨号呼叫,相当于发出连接请求(假如对方不在同一区内,还要拨对方区号,相当于给出网络地址)。对方假如在场并空闲(相当于通信的另一主机开机且可以接受连接请求),拿起电话话筒,双方就可以正式通话,相当于连接成功。双方通话的过程,是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向Socket发送数据和从Socket接收数据。通话结束后,一方挂起电话机相当于关闭Socket,撤消连接。
(2)IP地址
用来唯一标识网络上的主机,有IP4和IP6 2种。
(3)端口
网络中可以被命名和寻址的通信端口,是操作系统可分配的一种资源。
(4)协议
常见的连接层协议分为TCP和UDP 2种。TCP是面向连接的,UDP是面向无连接的。
(5)连接
两个进程间的通信链路称为连接。一般用一个五元组(本机ip、本机port、对端ip、对端port、协议)表示一个Socket连接。
1.2 服务器模型
Linux系统网络服务器模型主要有3种:并发服务器、循环服务器和IO多路复用服务器。
(1)TCP循环服务器:首先TCP服务器接受一个客户端的连接请求,处理连接请求,在完成这个客户端的所有请求后断开连接,然后再接受下一个客户端的请求。
(2)TCP并发服务器:并发服务器的思想是每一个客户端的请求并不由服务器的主进程直接处理,而是服务器主进程创建一个子进程来处理。
(3)多路复用I/O并发服务器:创建子进程会带来系统资源的大量消耗,为了解决这个问题,采用多路复用I/O模型的并发服务器。多路复用I/O可以解决资源限制问题,此模型实际上是将UDP循环模型用在了TCP上面。
2 运用Python进行网络编程
2.1 服务端/客户端示例
(1)客户端
(2)循环服务器
3 结语
介绍了Socket编程的基本概念和常见模型,并用Python实现了client和server示例脚本。最后给出了select模型,从例子中可以看出采用Python进行select服务器的编程简单、逻辑清晰。采用select模型最大的优点是在单线程中达到类似多线程处理网络连接的效果,其缺点是单进程打开的连接有限,并且随着连接的增多其处理效率会显著下降。
摘要:介绍了网络编程的基本概念和步骤,介绍了网络编程的服务端模型,说明了如何应用Python来进行网络程序的开发,详细介绍了select服务器模型,并通过一个简单实例说明select服务器模型的应用步骤。
关键词:Socket,select,server,client
参考文献
[1]Richard Stevens,TCP/IP Illustrated,Vol.1/Vol.2/Vol.3.
[2]Richard Stevens,UNIX Network Programming,2/e,Vol.1/Vol.2.
[3]http://docs.python.org/library/select.html.
Python编程 篇2
这篇文章主要介绍了Python实现数据库编程方法,较为详细的总结了Python数据库编程涉及的各种常用技巧与相关组件,需要的朋友可以参考下
本文实例讲述了Python实现数据库编程方法,分享给大家供大家参考。具体分析如下:
用PYTHON语言进行数据库编程, 至少有六种方法可供采用. 我在实际项目中采用,不但功能强大,而且方便快捷.以下是我在工作和学习中经验总结.
方法一:使用DAO (Data Access Objects)
这个第一种方法可能会比较过时啦.不过还是非常有用的. 假设你已经安装好了PYTHONWIN,现在开始跟我上路吧……
找到工具栏上ToolsàCOM MakePy utilities,你会看到弹出一个Select Library的对话框, 在列表中选择‘Microsoft DAO 3.6 Object Library‘(或者是你所有的版本).
现在实现对数据的访问:
#实例化数据库引擎import win32com.clientengine = win32com.client.Dispatch(“DAO.DBEngine.35”)#实例化数据库对象,建立对数据库的连接db = engine.OpenDatabase(r“c:/temp/mydb.mdb”)
现在你有了数据库引擎的连接,也有了数据库对象的实例.现在就可以打开一个recordset了. 假设在数据库中已经有一个表叫做 ‘customers‘. 为了打开这个表,对其中数据进行处理,我们使用下面的语法:
rs = db.OpenRecordset(“customers”)#可以采用SQL语言对数据集进行操纵rs = db.OpenRecordset(“select * from customers where state = ‘OH‘”)
你也可以采用DAO的execute方法. 比如这样:
db.Execute(“delete * from customers where balancetype = ‘overdue‘ and name = ‘bill‘”)#注意,删除的数据不能复原了J
EOF 等属性也是可以访问的, 因此你能写这样的语句:
while not rs.EOF: print rs.Fields(“State”).Value rs.MoveNext()
我最开始采用这个方法,感觉不错.
方法二:使用Python DB API,Python ODBC modules(you can use ODBC API directly, but maybe it is difficult for most beginner.)
为了在Python里面也能有通用的数据库接口,DB-SIG为我们提供了Python数据库.(欲知详情,访问DB-SIG的网站,www.python.org/sigs/db-sig/). Mark
Hammond的win32扩展PythonWin里面包含了这些API的一个应用-odbc.pyd. 这个数据库API仅仅开放了一些有限的ODBC函数的功能(那不是它的目的),但是它使用起来很简单,而且在win32里面是免费的.
安装odbc.pyd的步骤如下:
1. 安装python软件包:
www.python.org/download/
2. 安装Mark Hammond的最新版本的python win32扩展 - PythonWin:
starship.python.net/crew/mhammond/
3. 安装必要的ODBC驱动程序,用ODBC管理器为你的数据库配置数据源等参数
你的应用程序将需要事先导入两个模块:
dbi.dll - 支持各种各样的SQL数据类型,例如:日期-dates
odbc.pyd C 编译产生的ODBC接口
下面有一个例子:
import dbi, odbc # 导入ODBC模块import time# 标准时间模块dbc = odbc.odbc( # 打开一个数据库连接 ‘sample/monty/spam‘ # ‘数据源/用户名/密码‘ )crsr = dbc.cursor() # 产生一个cursorcrsr.execute( # 执行SQL语言 “”“ SELECT country_id, name, insert_change_date FROM country ORDER BY name ”“”)print ‘Column descriptions:‘ # 显示行描述for col in crsr.description: print ‘ ‘, colresult = crsr.fetchall() # 一次取出所有的结果print ‘/nFirst result row:/n ‘, result[0] # 显示结果的第一行print ‘/nDate conversions:‘ # 看看dbiDate对象如何?date = result[0][-1]fmt = ‘ %-25s%-20s‘print fmt % (‘standard string:‘, str(date))print fmt % (‘seconds since epoch:‘, float(date))timeTuple = time.localtime(date)print fmt % (‘time tuple:‘, timeTuple)print fmt % (‘user defined:‘, time.strftime(‘%d %B %Y‘, timeTuple))
下面是结果:
输出(output)
Column descriptions: (‘country_id‘, ‘NUMBER‘, 12, 10, 10, 0, 0) (‘name‘, ‘STRING‘, 45, 45, 0, 0, 0) (‘insert_change_date‘, ‘DATE‘, 19, 19, 0, 0, 1)First result row: (24L, ‘ARGENTINA‘, 大家也可以去www.python.org/windows/win32/odbc.html看看,那儿有两个Hirendra Hindocha写的例子,还不错. 注意, 这个例子中,结果值被转化为Python对象了.时间被转化为一个dbiDate对象.这里会有一点限制,因为dbiDate只能表示UNIX时间(1 Jan 1970 00:00:00 GMT)之后的时间.如果你想获得一个更早的时间,可能会出现乱码甚至引起系统崩溃.*_* 方法三: 使用 calldll模块 (Using this module, you can use ODBC API directly. But now the python version is 2.1, and I don‘t know if other version is compatible with it. 老巫:-) Sam Rushing的calldll模块可以让Python调用任何动态连接库里面的任何函数,厉害吧?哈.其实,你能够通过直接调用odbc32.dll里面的函数操作ODBC.Sam提供了一个包装模块odbc.py,就是来做这个事情的.也有代码来管理数据源,安装ODBC,实现和维护数据库引擎 (Microsoft Access).在那些演示和例子代码中,还有一些让人侧目的好东东,比如cbdemo.py,有一个信息循环和窗口过程的Python函数! [你可以到Sam‘s Python Software去找到calldll的相关连接,那儿还有其他好多有趣的东西] 下面是安装CALLDLL包的步骤: 1. 安装PYTHON软件包(到现在为止最多支持2.1版本) 2. 下载calldll--05-20.zip: ftp://squirl.nightmare.com/pub/python/python-ext/calldll-2001-05-20.zip 3. 在LIB路径下面创建一个新路径比如说: c:/Program Files/Python/lib/caldll/ 4. 在原目录下解压calldll.zip 5. 移动calldll/lib/中所有的文件到上面一个父目录(calldll)里面,删除子目录(lib) 6. 在CALL目录里面生成一个file __init__.py文件,象这样: # File to allow this directory to be treated as a python 1.5 package. 7. 编辑calldll/odbc.py: 在“get_info_word”和“get_info_long”里面,改变“calldll.membuf”为“windll.membuf” 下面是一个怎么使用calldll的例子: from calldll import dbcdbc = odbc.environment().connection() # create connectiondbc.connect(‘sample‘, ‘monty‘, ‘spam‘) # connect to db# alternatively, use full connect string:# dbc.driver_connect(‘DSN=sample;UID=monty;PWD=spam‘)print ‘DBMS: %s %s/n‘ % ( # show DB information dbc.get_info(odbc.SQL_DBMS_NAME), dbc.get_info(odbc.SQL_DBMS_VER) )result = dbc.query( # execute query & return results “”“ SELECT country_id, name, insert_change_date FROM country ORDER BY name ”“” )print ‘Column descriptions:‘ # show column descriptionsfor col in result[0]: print ‘ ‘, colprint ‘/nFirst result row:/n ‘, result[1] # show first result row output(输出) DBMS: Oracle 07.30.0000Column descriptions: (‘COUNTRY_ID‘, 3, 10, 0, 0) (‘NAME‘, 12, 45, 0, 0) (‘INSERT_CHANGE_DATE‘, 11, 19, 0, 1)First result row: [‘24‘, ‘ARGENTINA‘, ‘1997-12-19 01:51:53‘] 方法四: 使用ActiveX Data Object(ADO) 现在给出一个通过Microsoft‘s ActiveX Data Objects (ADO)来连接MS Access 数据库的实例.使用ADO有以下几个好处: 首先,与DAO相比,它能更快地连接数据库;其次,对于其他各种数据库(SQL Server, Oracle, MySQL, etc.)来说,ADO都是非常有效而方便的;再有,它能用于XML和文本文件和几乎其他所有数据,因此微软也将支持它比DAO久一些. 第一件事是运行makepy.尽管这不是必须的,但是它对于提高速度有帮助的.而且在PYTHONWIN里面运行它非常简单: 找到工具栏上ToolsàCOM MakePy utilities,你会看到弹出一个Select Library的对话框, 在列表中选择‘Microsoft ActiveX Data Objects 2.5 Library ‘(或者是你所有的版本). 然后你需要一个数据源名Data Source Name [DSN] 和一个连接对象. [我比较喜欢使用DSN-Less 连接字符串 (与系统数据源名相比,它更能提高性能且优化代码)] 就MS Access来说,你只需要复制下面的DSN即可.对于其他数据库,或者象密码设置这些高级的功能来说,你需要去 [Control Panel控制面板 | 管理工具Administrative Tools | 数据源Data Sources (ODBC)]. 在那里,你可以设置一个系统数据源DSN. 你能够用它作为一个系统数据源名,或者复制它到一个字符串里面,来产生一个DSN-Less 的连接字符串. 你可以在网上搜索DSN-Less 连接字符串的相关资料. 好了,这里有一些不同数据库的DSN-Less连接字符串的例子:SQL Server, Access, FoxPro, Oracle , Oracle, Access, SQL Server, 最后是 MySQL. >>>import win32com.client>>>conn = win32com.client.Dispatch(r‘ADODB.Connection‘)>>>DSN = ‘PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:/MyDB.mdb;‘>>>conn.Open(DSN) 经过上面的设置之后,就可以直接连接数据库了: 首要的任务是打开一个数据集/数据表 >>>rs = win32com.client.Dispatch(r‘ADODB.Recordset‘)>>>rs_name = ‘MyRecordset‘>>>rs.Open(‘[‘ + rs_name + ‘]‘, conn, 1, 3) [1和3是常数.代表adOpenKeyset 和adLockOptimistic.我用它作为默认值,如果你的情况不同的话,或许你应该改变一下.进一步的话题请参考ADO相关材料.] 打开数据表后,你可以检查域名和字段名等等 >>>flds_dict = {}>>>for x in range(rs.Fields.Count):... flds_dict[x] = rs.Fields.Item(x).Name 字段类型和长度被这样返回A : >>>print rs.Fields.Item(1).Type202 # 202 is a text field>>>print rs.Fields.Item(1).DefinedSize50 # 50 Characters 现在开始对数据集进行操作.可以使用SQL语句INSERT INTO或者AddNew() 和Update() >>>rs.AddNew()>>>rs.Fields.Item(1).Value = ‘data‘>>>rs.Update() 这些值也能够被返回: >>>x = rs.Fields.Item(1).Value>>>print x‘data‘ 因此如果你想增加一条新的记录,不必查看数据库就知道什么number 和AutoNumber 字段已经产生了 >>>rs.AddNew()>>>x = rs.Fields.Item(‘Auto_Number_Field_Name‘).Value # x contains the AutoNumber>>>rs.Fields.Item(‘Field_Name‘).Value = ‘data‘>>>rs.Update() 使用ADO,你也能得到数据库里面所有表名的列表: >>>Cat = win32com.client.Dispatch(r‘ADOX.Catalog‘)>>>oCat.ActiveConnection = conn>>>Tab = oCat.Tables>>>for x in oTab:... if x.Type == ‘TABLE‘:... print x.Name 关闭连接. 注意这里C是大写,然而关闭文件连接是小写的c. >>>conn.Close() 前面提到,可以使用SQL语句来插入或者更新数据,这时我们直接使用一个连接对象. >>>conn = win32com.client.Dispatch(r‘ADODB.Connection‘)>>>DSN = ‘PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=C:/MyDB.mdb;‘>>>sql_statement = “INSERT INTO [Table_Name]([Field_1], [Field_2]) VALUES (‘data1‘, ‘data2‘)”>>>conn.Open(DSN)>>>conn.Execute(sql_statement)>>>conn.Close() 最后一个例子经常被看作是ADO的难点.一般说来,想要知道一个表的RecordCount 的话,必须象这样一个一个地计算他们 : >>># See example 3 above for the set-up to this>>>rs.MoveFirst()>>>count = 0>>>while 1:... if rs.EOF:... break... else:... count = count + 1... rs.MoveNext() 如果你也象上面那样些程序的话,非常底效不说,如果数据集是空的话,移动第一个记录的操作会产生一个错误.ADO提供了一个方法来纠正它.在打开数据集之前,设置CursorLocation 为3. 打开数据集之后,就可以知道recordcount了. >>>rs.Cursorlocation = 3 # don‘t use parenthesis here>>>rs.Open(‘SELECT * FROM [Table_Name]‘, conn) # be sure conn is open>>>rs.RecordCount # no parenthesis here either186 [再:3是常数] 这些只用到ADO的皮毛功夫,但对于从PYTHON来连接数据库,它还是应该有帮助的. 想更进一步学习的话,建议深入对象模型.下面是一些连接: msdn.microsoft.com/library/default.asp?url=/library/en-us/ado270/htm/mdmscadoobjmod.asp www.activeserverpages.ru/ADO/dadidx01_1.htm (单步执行还可以,为何写为script就不行?老巫疑惑) 方法五:使用 mxODBC模块(在Windows和Unix下面都可以用,但是是商业化软件,要掏钱的.)下面是相关连接: thor.prohosting.com/~pboddie/Python/mxODBC.html www.egenix.com/files/python/mxODBC.html 方法六: 对具体的数据库使用特定的PYTHON模块 MySQL数据库à MySQLdb模块,下载地址为: sourceforge.net/projects/mysql-python PostgresSQL数据库àpsycopg模块 PostgresSQL的主页为: www.postgresql.org Python/PostgresSQL模块下载地址: initd.org/software/psycopg Oracle数据库àDCOracle模块下载地址: www.zope.org/Products/DCOracle àcx_oracle模块下载地址: freshmeat.net/projects/cx_oracle/?topic_id=809%2C66 1 传统编程教学活动的特点 传统编程教学活动存在一些显而易见的问题: 1.1 冗长的语法学习过程 目前在高等教育学校的编程学习中, 几乎无一例外的以C、C++、C#、VB.net或java等为主, 其中VB.net相对还是比较好掌握的编程语言, 而C、C++所属强类型编程语言语法的复杂, 及大量出现的语法陷阱使得学生在大多数的时间里成为一个“纠错者”, 在学习过程中花费不菲的时间来修正代码中的错误和漏洞, 而忽视了编程思想的培养, 容易造就会编程语言工具、不会实现编程工作的现象。C#虽然是一种较好的面向对象编程语言, 但在实现上对计算机环境的配置要求还比较高, 对一些资金上比较紧张的学校机房来说, 更新设备的代价太大, 同时由于C#不支持除windows以外的平台, 造成某些欲在非windows系统环境下学习的学生缺乏相关的学习环境。 1.2 校内授课制度的局限 编程语言的学习是一个长期和持续的过程, 往往对时间上的需求较多。而学校教学活动的局限性, 如为避免课程与课程的冲突、不能对编程课程进行集中授课, 而是像学习历史、政治一样分节学习, 造成上节课学习的内容这节课就忘记的现象比比皆是。编程类课程在客观上本就容易令学生产生厌学情绪和学习的枯燥感, 而学生迫于就业压力往往产生在校内学习、课外还报修各种社会编程学习班的普遍现象。 1.3 对学生自身学习背景的强烈依赖不利于非计算机专业学生的自修 学习上历来是“师傅领进门, 修行在个人”, 教师不论教学能力多高, 最终起到的还是一个启蒙的作用。然而, 一门过于难以掌握的语言大幅度提高了学生自己持续学习的难度。比如C语言的学习, 要求学生具有较扎实的计算机背景, 对堆栈、内存、指针、数组等有较深入的了解, 对代码的书写有诸多严格的要求。对外专业或计算机背景知识不扎实的学生来说, 查看程序代码如看天书, 书写产生错误的时候又找不到究竟是书写错误还是逻辑错误。一来二去很容易就此放弃。 2 Python在教学中能起到的作用 2.1 降低了学习的难度 Python的代码书写规则与计算机算法中的“伪代码”极其相似, 由于其最初被发明的时候就是为了增强其易用性 (Guido van Rossum参考了ABC语言的特性进行了开发) , 其语言的书写接近于日常英语, 可以说只要略加学习, 就可以迅速掌握, 这对教学资源的节约起到很好的作用;python对unicode字符集全面支持, 我们不用去考虑ascii字符集的字节存储空间问题 (unicode字符在其它语言中都存在较复杂的转换问题) , 而直接编写出可以被执行的小程序;由于python强大的序列 (Python的序列包括各类定长数组、动态数组、字符串等等的特性) 操作能力, 使得在同一个序列中放置不同数据类型的数据成为轻而易举的事, 我们不必再进行复杂的组合变量声明和处理;python隐藏了所有指针的行为, 所有的变量值都是引用类型, 令我们掌握起来更加容易。 而Python自身的IDLE不论是在windows上还是在UNIX上都有很好的支持。只需要对python进行简单的入门学习, 就可以迅速在短时间内书写出执行效率高的代码。 2.2 增强学生学习的动力 由于抛开了对专业背景的过度依赖, 使得非计算机专业的学生也有可能快速掌握并进行编程实践, 极大地提高了学生对编程思想的理解。在国内存在着数量庞大的编程爱好者, 这些爱好者往往没有经过系统的计算机理论的学习, 而Python的易用性基本可以克服这种对专业知识的过分依赖, 面向用户的设计和偏重程序逻辑的编码方式让人从“计算机式思考”解脱出来, 进入提升编程思路的良性循环中来。 2.3 强大的类库降低编程的复杂性 Python有强大的各种类库的支撑, 大量开源、免费的编程资源的存在和便于布置使得很容易快速实现开发和测试。Python是开源的, 这意味着为了工作的方便性, 我们可以自行扩展Python的库, 实现有自己风格特色的类库。 3 Python的未来需求 就业作为高校教学目的之一, 未来必然会逐步加强对学生就业能力的培养。Python作为一门较新的编程语言, 经过最近几年的逐步推广, 现在已渐渐成为一门热门的程序语言, 未来的就业前景广阔。Python贴合自然语言的伪代码风格和注重编程逻辑的编程方式, 注定会在未来有广阔的应用。学生通过不同课程、不同知识采用它来编写小程序, 来理解相关理论知识, 对学生理论联系实际的能力的提高具有一定作用, 同时对其它编程语言的学习也起到较强的辅助作用。 参考文献 [1][美]Mark Summerfield, 著.王弘博, 孙传庆, 译.《Python3程序开发指南》 (第二版) .[1][美]Mark Summerfield, 著.王弘博, 孙传庆, 译.《Python3程序开发指南》 (第二版) . 考虑这种情况:如果一个线程遇到锁嵌套的情况该怎么办,这个嵌套是指当我一个线程在获取临界资源时,又需要再次获取, 根据这种情况,代码如下: 代码如下: ‘‘‘ Created on -9-8 @author: walfred @module: thread.ThreadTest6 ‘‘‘ import threading import time counter = 0 mutex = threading.Lock class MyThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): global counter, mutex time.sleep(1); if mutex.acquire(): counter += 1 print “I am %s, set counter:%s” % (self.name, counter) if mutex.acquire(): counter += 1 print “I am %s, set counter:%s” % (self.name, counter) mutex.release() mutex.release() if __name__ == “__main__”: for i in range(0, 200): my_thread = MyThread() my_thread.start() 这种情况的代码运行情况如下: 代码如下: I am Thread-1, set counter:1 之后就直接挂起了,这种情况形成了最简单的死锁, 那有没有一种情况可以在某一个线程使用互斥锁访问某一个竞争资源时,可以再次获取呢?在Python中为了支持在同一线程中多次请求同一资源,python提供了“可重入锁”:threading.RLock。这个RLock内部维护着一个Lock和一个counter变量,counter记录了acquire的次数,从而使得资源可以被多次require。直到一个线程所有的acquire都被release,其他的线程才能获得资源。上面的例子如果使用RLock代替Lock,则不会发生死锁: 代码只需将上述的: 代码如下: mutex = threading.Lock() 替换成: 代码如下: mutex = threading.RLock() 【Python编程】推荐阅读: Python脚本06-13 Python语言06-26 Python技术08-27 python语法汇总08-03 python采集百度百科的方法08-01 python爬取网站数据保存使用的方法08-28 Python实现过滤单个Android程序日志脚本06-18 Python实现动态添加类的属性或成员函数的解决方法06-09 自动编程06-01Python编程 篇3
Python编程 篇4