Mar 2

源自 Learning Python第三版

内置对象让写程序变得容易

对于简单任务,内置对象通常是你解决问题所需要的全部.因为你可以自由(便利)地使用这些强大的工具,比如集合(列表)和检索表(字典),你可以直接使用它们.你只需要使用Python的内置对象就可以完成大量的任务.

内置对象是拓展的组件

对于更复杂的任务,你可能还是需要使用Python的类或者C语言接口来构建自己的对象.但是,正如你接下来在本书看到的一样,自定义对象通常建立在内置对象之上,比如列表和字典.比方说,一个堆栈结构可能是通过调用或者自定义内建的列表来实现的.

内置对象通常比自定义数据结构更高效

Python的内置对象为了执行效率,已经采用C语言实现优化的数据结构算法.尽管你可以自己写出更小的的对象类型,但是你常常会纠结于获得跟内置对象一样的性能.

内置对象是Python语言标准的一部分

在某些方面,Python既借用了那些依赖于内置工具的语言(的特性), 比如说LISP,又借用了那些依赖于语言本身的编程提供工具或者框架(的特性),比如说C++.尽管你可以在Python里实现一些独特的类型,但你并不需要这么做,所以,只要用(内置对象)就好了. 更进一步说,因为Python内置对象是标准的,它们(提供的接口)通常都一样;另一方面,专有框架趋向于各自不同.

换句话说,内置对象不只是使写程序更容易,而且它们比多数手工创建的类型要强大高效得多.不管你实现了什么新对象,内置对象构成了每一个Python程序的核心.

 

译后感言: 读英文容易,但是要译成中文,却费了很多功夫.

Feb 27

问题的由来: 刻录了一百多张光盘, 记录了每一张光盘的目录数(光盘根目录下的一层子目录), 发现光盘目录数总和大于源数据目录数. 应该是 一个目录只能刻录在一张光盘上, 所有光盘下目录总数等于源数据目录总数, 不多不少

于是得校验到底是哪些光盘里的目录是重复了. 光盘有相应的标签...

如果是一台机依次读取一百来个光盘,那还真够呛的. 所以,得分开来读,得到一些原始数据再合并对比. 标识光盘,当然是其标签, 已经确定了,标签不存在重复. 所以,我想到用字典来处理.

#!/usr/bin/env python3
#coding=gbk
import os
import ctypes
import win32api

def get_write():
    cdrom = "E:"
    k = win32api.GetVolumeInformation(cdrom)[0]
    dirs = os.listdir(cdrom)
    ctypes.windll.WINMM.mciSendStringW(u"set cdaudio door open", None, 0, None)
    print("光驱已经弹出, 请换光盘继续")
    return (k, dirs)

mydict = {}
ans = input("装光盘放入光驱后, 按回车键继续\n>")
while ans != 'q':
    k, v = get_write()
    mydict[k] = v
    ans = input("装光盘放入光驱后, 按回车键继续,输入q退出\n>")

for k, v in mydict.items():
    print(k, v)

字典的键是光盘标签, 键值是目录列表

cdrom 暂时定为E盘, 还找到获取第一个光驱的盘符的办法

Jun 5

在列表中,搜索元素比较头痛,一般只会得到第一个元素的索引,这里,我改变了搜索过的元素。当然,实际操作中,是需要把列表复制的 如 d=c[:] 再对d进行处理。

此代码来自一个问题:

yjcong

这个, 我不晓得是哪个术语对应, 所以加了个引号.

问题有2个,

1) 在一个文件中, 如何在定位的"abcxyz"后, 如何显示其下一行的内容. 若是有很多个, 如何?

2) 假设搜索的关键字在第n行, 如何同时显示第n-1, n, n+1行的内容

thx

问题二在帖子中已经解决,不再处理。http://forum.ubuntu.com.cn/viewtopic.php?f=21&t=443359&p=3007102#p3007102

关键词改为熟悉的foo

 

 

测试用例

foo
akjkdjkejwl
rkewjlkrjwelk
foo
fewkjk1kl1l2l1212l1
fewkjrkewjn mnfmenw
ewkjrkjwl
barfoofwerjwekjr
barofwerjwekjr
 

输出结果

 

akjkdjkejwl

fewkjk1kl1l2l1212l1

barofwerjwekjr

 





#!/usr/bin/env python3
import re

def fun(c):
     for i in c:
         if re.findall('foo',i):
                 try:
                         print(c[c.index(i)+1])
                         c[c.index(i)] += 'someword' 
                 except:
                         print("keyword is in the last line")

 #f=open('d:/1')
 #c=[]
#[c.append(i) for i in f.readlines()]
 #fun(c)
fun(open('d:/1').readlines())

 

 

May 14

 如题所述,凭着折磨的精神,终于搞定。

依照这篇文章,完成了一部分,可是出现一些问题。

http://www.cnblogs.com/ddr888/archive/2010/05/16/1736990.html cx_Oracle说:Python访问Oracle并不难

原文全拿过来了。不管了,

 

标题很好的说明cx_Oracle的意义,但是就像Windows下访问Oracle那样麻烦一样,Debian中一样繁琐,本文将用尽量简单的过程介绍在Debian 5中Python访问Oracle,但cx_Oracle的使用请参考文档。

  Python实现对Oracle的访问需要以下两个组件和一个可选组件:
Oracle Instant Client 它是Oracle提供的一个简单的访问Oracle的组件,不用安装Oracle标准客户端。
cx_Oracle 一套符合python 数据库API规范的Oracle访问组件。
alient(可选) 简单来讲,就是能把RHEL下的程序包(.rpm)和基于Debian系统中的程序包(.dpkg)相互转换的工具。
一、Oracle Instant Client安装
  It is free!它提供了Oracle数据库访问的C语言接口OCI,cx_Oracle就是通过OCI访问数据库,所以如果只需要在客户端访问数据库,它就是最轻量的。注册并下载Basic包,里面有几个库文件,我们要做的是在cx_Oracle能使用OCI提供的接口,即把Basic包中的几个库文件加入Debian的共享库中。
?1
2
3 #mkdir /opt/oracle/instantclient
#cp Basic包中文件 /opt/oracle/instantclient
#vi /etc/profile

在底部加入以下指令:
?1 export LD_LIBRARY_PATH="/opt/oracle/instantclient/"

程序运行时一般会从系统默认的路径中查找共享库文件:/lib和/usr/lib。如果存在环境变量LD_LIBRARY_PATH,那么会先从这里查找库文件,有了这些库文件就可以安装cx_Oracle。
二、安装cx_Oracle
  cx_Oracle是Python中访问Oracle的一个扩展组件,也是很多地方推荐的方案。但是官方网站上并没有提供基于Debian系统类型的安装包,但是有rpm包,这里可以通过alient转换rpm转换到dpkg的折中方法来安装,当然也可以源码安装。
?1
2
3 #apt-get install alient
#alient cx_Oracle-*.*.*.*.rpm
#dpkg -i cx_Oracle-*.*.*.*.dpkg

三、cx_Oracle使用
  这里只介绍它的简单使用方法:
?1
2
3
4 import cx_Oracle
db = cx_Oracle.connect('username', 'pwssword', 'ip_address:1521/db_name')
print db.dsn
print db.version

小结
  本文记录了Debian中Python访问Oracle数据库的cx_Oracle的设置方法,如果有其他方法的经验,欢迎讨论。

别的就不说了。说遇到的问题,一直以来我用的是ubuntu,现在 改用debian。坑啊,没注意python版本差别,我一直以为是3.3哪知道 debian python3是3.2, 郁闷

好,再一个是路径设定,要看清楚。还有就是python的搜索路径,你mm的,没包含 /usr/lib/python3.2/site-packages 。。。

放狗搜索,解决了。btw,最近google越来越难用,修墙,不要修太强啊。所谓IT人为难IT人啊。。。何必呢

 

上网找了很多久未果,都来我自己糊里糊涂找到了解决方法,那就是在dist-packages(即/usr/local/lib/python2.6/dist-packages)添加一个路径文件,如mypkpath.pth,必须以.pth为后缀,写上你要加入的文件名称就是了,如我的:

/home/tony/tst-python

呃。最坑的就是最后出现了一个  

>>> import cx_Oracle
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: libaio.so.1: cannot open shared object file: No such file or directory

这样的错误。一看,直觉告诉我,这应该是libaio包缺失。。。好吧。先找debian 郁闷 sid排在前面,继续找,找到这个网站http://pkgs.org/download/libaio,也安装了,还是没找到文件。。。

再一想,不对, 既然是 Linux-native asynchronous I/O access library 那当然在源里的。立即apt-get install libaio 

呃,tab几下,你妹妹的,出现三个,选1那个安装了。世界和平了。。。。

 

>>> import cx_Oracle
>>> db = cx_Oracle.connect('foo/bar@127.0.0.1/bar')
<cx_Oracle.Connection to foo@127.0.0.1/bar>
>>> db.dsn
'127.0.0.1/bar'
>>> db.version
'9.2.0.1.0'

Aug 16

案例法确实值得称赞,虽然是“笨办法”,一字不差,没有任何含糊,不过它确实有效,那么它就不笨。

因欲写个重命名的工具(其实之前有用shell写过),后来觉得代码相当ugly,想换个方式来实现它。尝试过perl, 无奈,熟悉正则表达式的我表示无力,太不人性了(也许我要被喷了,^_^),于是转向python,。之前有接触过,教材不对,学习方法不对,我还没入门就撤退了。现在我选择“笨办法”,也确实学到点东西了。

下面是参考另人的代码写的一个小工具,实现操作:连接oracle数据库,导出列,以某一列为原始文件名,另外一列为新文件名,批量重命名文件,并移动到目标路径。

网上查过,移动文件python的效率不高,我就改用了系统命令 move, 在传递参数时,也许会造成困扰,不过我之前刚好看过c语言传递参数(先用sprintf把命令及参数存到一个变量,然后那个变量作为参数传入system())我也照着去做,实现了参数传递,程序是相通的。

说明:@foo 其中,foo是实例名。

 

import sys
import os
from os.path import exists
import cx_Oracle
import py2exe

reload(sys)
sys.setdefaultencoding('utf-8')

def getdata(chah):
     try:
         conn = cx_Oracle.connect("system/foo@foo")
         try:
             cur = conn.cursor()
             sql = """select yh,imgname from foo where 
             chah='%s' order by yh""" % chah
             cur.execute(sql)
             allData = cur.fetchall()
         finally:
             cur.close()
             conn.close()
     except Exception, e:
         print '数据库错误:', e
         return

     for rec in allData:
         oldname = "%s.jpg" %rec[0]
         newname = rec[1]
         if exists(oldname) and not exists(newname):
            os.rename(oldname,newname) 
            print "%s => %s" %(oldname, newname)
         else:
             return 0

print "\nchah ?(quit: input q and hit ENTER)"
chah = raw_input(">")
while chah != 'q':
     print "Running..."
     getdata(chah)
     target = "d:\%s" % chah
     action = "move *.jpg %s" % target
     os.system(action)
     print "\nchah is %s" % chah
     print "\nchah ?(quit: input q and hit ENTER)"
     chah = raw_input(">")

关于连接oracle数据库,遇到一些问题,着实花了我不少时间,幸好网上都有答案,感谢国家,感谢党,感谢人民,感谢google.

不说遇到的问题,就说怎么做吧。

python版本 2.7

oracle 版本 9.2.0.4

先下载两个文件

1、cx_Oracle-5.1.2-10g.win32-py2.7.msi

2、instantclient-basic-win32-10.2.0.4.zip 这是从oracle官网下载的,坑人啊,33+M, 还非常难下载!幸好有离线服务器,再次感谢……

 

第一步,安装cx_Oracle-5.1.2-10g.win32-py2.7.msi

第二步,从instantclient-basic-win32-10.2.0.4.zip解压oraocci10.dll、oci.dll、oraociei10.dll放到C:\Python27\Lib\site-packages

第三步,设定环境变量我懒得去分析了,直接上配置

系统变量  

NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

ORACLE_HOME=D:\oracle\ora90

路径PATH

D:\oracle\ora90\bin;D:\oracle\ora90\Apache\Perl\5.00503\bin\mswin32-x86;C:\Program Files\Oracle\jre\1.1.8\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%JAVA_HOME%\bin;C:\Program Files\Vim\vim73;d:\php5;D:\bin;C:\Program Files\MySQL\MySQL Server 5.5\bin\;d:\php5;D:\php5\ext;d:\nginx;C:\Program Files\SMPlayer\mplayer;c:\mingw\bin;C:\Python27\Lib

Aug 18
关键字 释义
and 逻辑与
assert  
as 作为
break 中断
class
continue 继续
def 定义函数
del 删除
elif 条件else if
else 条件else
except 异常处理
exec 执行
finally 最后
for for 循环
from 导入模块用
global 定义全局变量
if 条件if
import 导入模块
in 在...
is
lambda lambda 定义匿名函数
not 逻辑否
or 逻辑或
pass 跳过
print 打印
raise 引起异常
return 返回
try 尝试
while 当条件为真执行循环
with with 伴随???
yield 用在函数中, 先不计算,保留着

数据类型

布尔 True False

空类型 None

字符串 strings

数字型 numbers

浮点数(小数) floats

列表 lists

转义序列

跟c语言一样

字符串格式化

%d 十进制

%i

%o 8进制

%u

%x 

%X

%e

%E

%f 小数

%F

%G

%g

%c

%r 原样输出

%s 字符串

%% %

操作符

+ - * /  <  >  >=  <= == !=跟数学一样

** a**n表示a的n次方

// 取整如100//6=16, 乘以除数+取余可以得被除数。100 // 6 * 6 + 100 % 6 = 100

% 取余数(mod)

<>

() 定义元组或者函数参数 def a(x): pass

[] 列表

{} 集合或者是字典

@ 装饰符

, 对象之间的分隔符(或者叫做连接符)如 print "foobar", var (var为变量)

:  def foobar(): 或者for x in a: 多行语句 

. 方法操作符

= 赋值

;  +=  -=  *=  /=  //= %= **=  跟c一样

有些符号我还没搞懂,日后再完善了。