2010/03/14

Python 简明学习笔记(三)

九:面向对象编程
类使用class关键字创建,类的域和方法被列在一个缩进中。

定义在类中的方法必须有一个额外的第一参数名称,按照惯例它的名称为self,它指的是对象本身。python中的self相当于Java中的this。

eg:
#!/usr/bin/python
#Filename:simplecalss.py

class Person:
    def sayHello(self):
        print'hello ,how are you ?'

p=Person()
p.sayHello()
#也可写作Person().sayHello()

__init__方法:相当于Java中的构造器,在类的第一个对象被建立时,立即运行。用于对对象做一些初始化。

#!/usr/bin/python
#Filename:class_init.py

class Person:
    def __init__(self,name):
        self.name=name
    def sayHello(self):
        print'hello, my name is ',self.name

p=Person('anix')
p.sayHello()

output:
$python class_init.py
hello, my name is anix
#有两种类型的域——类的变量和对象的变量。他们是根据是类还是对象拥有这个变量而区分的。self.name=name:Person('anix')是将anix传递给类,此时name是类变量,self.name=name将类变量赋值给对象变量。(self指的是对象本身)。

类的变量由一个类的所有对象(实例)共享使用,所以当某个对象对类的变量作出的改动会影响所有该类的实例。

对象的变量由每个对象/实例拥有。每个对象有自己对这个域的一份拷贝,所有当某个对象对对象的变量作出的改动不会影响其他该类的实例。

eg:

#!/usr/bin/python
#Filename:objvar.py

class Person:
    '''represents a person'''
    population=0

    def __init__(self,name):
        '''initializes the person's data'''
        self.name=name
        print'(initializing %s)'% self.name
        Person.population++

    def __del__(self):
        print'%s says goodbye.'% self.name   
        Person.population--
        if Person.population==0:
            print'i am the last one'
        else:
            print'there is %d people left.' % \
                    Person.population
   
    def sayHello(self):
        print'hello, my name is %s' % self.name

    def howMany(self):
        if Person.population==1:
            print'i am the only person here'
        else:
            print'there are %d persons here' %\
                     Person.population

anix=Person('anix')
anix.sayHello()
anix.howMany()

chris=Person('Chris')
chris.sayHello()
chris.howMany()

anix.__del__()
anix.howMany()

#population属于Person类,是类变量。
#name是对象变量,它使用self赋值。
#__del__方法在对象不再被时候时运行(相当于Java中的system.gc()),当需要指明它何时运行时就得使用与此例相似的del语句。

output:
(initializing anix)
hello, my name is anix
i am the only person here'
(initializing Chris)
hello, my name is Chris
there are 2 person here
anix says goodbye
i am the only person here'

继承:

eg:

#!/usr/bin/python
# Filename: inherit.py

class SchoolMember:
    '''Represents any school member.'''
    def __init__(self, name, age):
        self.name = name
        self.age = age
        print '(Initialized SchoolMember: %s)' % self.name
    def tell(self):
    '''Tell my details.'''
        print 'Name:"%s" Age:"%s"' % (self.name, self.age)

class Teacher(SchoolMember):
    '''Represents a teacher.'''
    def __init__(self, name, age, salary):
        SchoolMember.__init__(self, name, age)
        self.salary = salary
        print '(Initialized Teacher: %s)' % self.name
    def tell(self):
        SchoolMember.tell(self)
        print 'Salary: "%d"' % self.salary

class Student(SchoolMember):
    '''Represents a student.'''
    def __init__(self, name, age, marks):
        SchoolMember.__init__(self, name, age)
        self.marks = marks
        print '(Initialized Student: %s)' % self.name
    def tell(self):
        SchoolMember.tell(self)
        print 'Marks: "%d"' % self.marks

t = Teacher('Mrs. Shrividya', 40, 30000)
s = Student('Swaroop', 22, 75)
print # prints a blank line
members = [t, s]
for member in members:
    member.tell() # works for both Teachers and Students

输出
$ python inherit.py
(Initialized SchoolMember: Mrs. Shrividya)
(Initialized Teacher: Mrs. Shrividya)
(Initialized SchoolMember: Swaroop)
(Initialized Student: Swaroop)
Name:"Mrs. Shrividya" Age:"40" Salary: "30000"
Name:"Swaroop" Age:"22" Marks: "75"



十:I/O

文件:通过创建file类对象打开一个文件,使用file类的read write readline方法来恰当地读写文件,然后调用close方法关闭文件。

#!/usr/bin/python
#Filename:using_file.py

poem='''\
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!
'''
f=file('poem.txt','w')
f.wirte(peom)
f.close()

f=file('poem.txt') #默认为'r'ead模式
while True:
    line=f.readline()
    if len(line)==0:
        break
    print line
f.close()

#文件的模式:读模式('r');写模式('w');追加模式('a')

output:
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!


储存器:python提供名为pickle的标准模块,使用它可以在一个文件中储存任何python对象,并完整取出来。这被称为持久地储存对象。
另外还有一个模块叫 cPickle,用C语言实现,功能和pickle模块完全相同,但速度比pickle模块快1000倍。

dump(obj,file) load(file)
eg:

#!/usr/bin/python
#Filename:pickling.py

import cPickle as p

shoplistfile='shoplist.txt'
shotlist=['apple','orange','egg','banana','fish','beef','celery']

#write to the file
f=file(shoplistfile,'w')
p.dump(shoplist,f) #dump the object to the file
f.close()

#pick up from the storage
f=file(shoplistfile)
storedlist=p.load(f)

print storedlist

output:
['apple','orange','egg','banana','fish','beef','celery']


十一:异常 exceptions

try...except语句处理异常。


eg:
#!/usr/bin/python
#Filename try_except.py

import sys

try
    s=raw_input('enter something')
except EOFError:
    print'\n EOF error'
except:
    print'\n some error/exception occurred.'
print 'Done.'


raise 引起异常:
#!/usr/bin/python
#Filename :raising.py

import sys

calss ShortInputException(Exception):
    '''a user-defined exception'''
    def __init__(self,length,atleast):
        Exception.__init__(self)
        self.length=length
        self.atleast=atleast

try:
    s=raw_input('enter something:')
    if len(s)<3:
        raise ShortInputException(len(s),3)
except EOFError:
    print'\n EOF error.'
except ShortInputException,x:
    print'shortinput exception: the input was of length %d,\
        was excepting at least %d'%(x.length,x.atleast)
else:
    print'NO exception was raised.'



try...finally语句:
#!/usr/bin/python
#Filename: finally.py

import time

try:
    f=file('poem.txt')
    while True:
        line=f.readline()
        if len(line)==0:
            break
        time.sleep(2)
        print line
finally:
    f.close()
    print'close file'



十二:python标准库

在python附带的安装文档的“库参考”一节中有python所有模块的完整内容。

sys模块:包含系统对应的功能。

eg:使用sys.argv,实现unix下 cat功能:

#!/usr/bin/python
#Filename:cat.py

import sys

def readfile(filename):
    f=file(filename)
    while True:
        line=f.readline()
        if len(line)==0:
            break
        print line
    f.close()

if len(sys.argv)<2:
    print'no action specified'
    sys.exit()

if sys.argv[1].startswith('--'):
    option=sys.argv[1][2:]
    if option=='version':
        print'version 1.2'
    elif option=='help':
        print '''\
    this program prints files to standard output
    '''
    else:
        print 'unknown option.'
    sys.exit()
else:
    for filename in sys.argv[1]:
        readfile(filename)



os模块:包含普遍的操作系统功能,对解决跨平台问题十分重要。如使用os.sep可以取代操作系统特定的路径分隔符。

常用部分:
● os.name字符串指示你正在使用的平台。比如对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'。
● os.getcwd()函数得到当前工作目录,即当前Python脚本工作的目录路径。
● os.getenv()和os.putenv()函数分别用来读取和设置环境变量。
● os.listdir()返回指定目录下的所有文件和目录名。
● os.remove()函数用来删除一个文件。
● os.system()函数用来运行shell命令。
● os.linesep字符串给出当前平台使用的行终止符。例如,Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'。
● os.path.split()函数返回一个路径的目录名和文件名。
>>> os.path.split('/home/swaroop/byte/code/poem.txt')
('/home/swaroop/byte/code', 'poem.txt')
● os.path.isfile()和os.path.isdir()函数分别检验给出的路径是一个文件还是目录。类似地,os.path.exists()函数用来检验给出的路径是否真地存在。


十三:更多内容

·特殊的方法:
一般来说,特殊的方法都被用来模仿某个行为。例如,如果想使用x[key]这样的索引操作(如列表和元组),那么只需要实现__getitem__()方法就可以了。

一些常见的特殊方法:

    名称                    说明
__init__(self,...)     这个方法在新建对象恰好要被返回使用之前被调用。
__del__(self)          恰好在对象要被删除之前调用。
__str__(self)          在我们对对象使用print语句或是使用str()的时候调用。
__lt__(self,other)     当使用 小于 运算符(<)的时候调用。类似地,对于所有
             运算符(+,>等等)都有特殊的方法。
__getitem__(self,key)     使用x[key]索引操作符的时候调用。
__len__(self)          对序列对象使用内建的len()函数的时候调用。



·单语句块:
大多数情况下,python每个语句块是通过它的缩进层次与其他块区分开的。但如果语句块只包含一句指令,可以在条件语句或循环语句的同一行指明它,如:
>>>flag=True
>>>if flag : print 'yes'

>>>for filename in sys.argv[1]: readfile(filename)


·列表综合:
通过列表综合,可以从一个已有列表中导出新的列表。例如:已知一个数列,希望得到一个对应的数列,原数列中所有大于2的数都是原来的2倍:

#!/usr/bin/python
#Filename:list_comprehension.py

listone=[2,3,4]
listtwo=[2*i for i in listone if i>2]
print listtwo

output:
[6,8]


·在函数中接收元祖和列表:
当要使函数接收元祖或字典形式的参数时,有一种特殊方法,它分别使用*和**前缀,这种方法在函数需要获取数量可变的参数时候十分有用。
>>>def powersum(power,*args):
    total=0
    for i in args:
        total+=pow(i,power) #即i^power
    return total

output:
>>>powersum(2,3,5)
25
>>>powersum(2,10)
100


·lambda形式
lambda语句被用来创建新的函数对象,并在运行时返回他们。
eg:使用lambda形式

#!/usr/bin/python
#Filename:lambda.py

def make_repeater(n):
    return lambda s:s*n

twice=make_repeater(2)

print twice('word')
print twice(5)

#make_repeater函数在运行时创建新的函数对象,并返回它。lambda语句用来创建函数对象。
#本质上,lambda需要一个参数(这里是s),后面仅跟单个表达式作为函数体(这里是s*n),函数体(表达式)的值作为被lambda新建的函数返回(这里返回s*n的值)。


·exec和eval语句:
exec语句用来执行存储在*字符串*或*文件*中的python语句,例如我们可以在运行时生成一个包含python代码的字符串,然后使用exec语句执行之:
>>>exec 'print"hello world"'
hello world

eval语句用于计算存储在字符串中的有效python表达式:
>>>eval('2**3')
8
#'2**3'是一个字符串,因为被''罩住。


·assert语句:
assert语句用来声明某个条件是真的。例如,如果你非常确信某个你使用的列表中至少有一个元素,而你想要检验这一点,并且在它非真的时候引发一个错误,那么assert语句是应用在这种情形下的理想语句。当assert语句失败的时候,会引发一个AssertionError。

>>>mylist=['list']
>>>assert len(mylist)>=1
>>>mylist.pop()        #弹出mylist列表中元素并输出
list
>>>assert len(mylist)>=1
Traceback (most recent call last):
File "", line 1, in ?
AssertionError


·repr函数:
repr函数用来取得对象的规范字符串表示。反引号(也称转换符)可以完成相同的功能。注意,在大多数时候有eval(repr(object)) == object。

>>> i = []
>>> i.append('item')        #向列表中增加条目
>>> `i`
"['item']"
>>> repr(i)
"['item']"

基本上,repr函数和反引号用来获取对象的可打印的表示形式。你可以通过定义类的__repr__方法来控制你的对象在被repr函数调用的时候返回的内容。



十四:
www.google.com ,它会告诉你想要知道的一切. ^_^






注:此教程是我在2010寒假中学习Python的学习笔记。

没有评论:

发表评论