Python核心编程 杂

8-1
(a) C
(b) D
(c) B
8-2
def xun(f,t,i):
return [x for x in range(f,t+1,i)]
8-3:
(a) range(0,10)
(b) range(3,19,3)
(c) range(-20,900,220)
8-4:

def isprime(num):
    count=num/2
    while count>1:
        if num%count==0:
            return False
            break
        count-=1
    else:
        return True
for e in range(10,21):
print isprime(e)

8-5

# -*- coding: cp936 -*-

def get(x):
    a=[]
    b=[]
    for i in range(1,x+1):
        if x%i==0:
            a.append(i)

    print a
    for j in a:
        print j/2
        c=j/2
        while c>1:
            if j%c==0:
                break
            c-=1
        else:

            b.append(j)
        print b

'''
a=int(raw_input('Input a integer:'))
'''

8-7

def isperfect(x):
    a=[]
    b=[]
    for i in range(1,x):
        if x%i==0:
            a.append(i)
    if sum(a)==x:
        return 1
    else:
        return 0

8-8

def factorial(x):
    m=1
    for i in range(1,x+1):
        m*=i
    return m

8-9

def fib(x):
    if x==1 or x==2:
        return 1
    else:
        return fib(x-1)+fib(x-2)

8-11

print 'Enter total number of names: 5'
d=dict()
count=0
for i in range(5):
    b=raw_input('Please enter name '+str(i)+':' )
    b=b.split()
    if ',' not in b[0]:
        count+=1
        print 'Wrong format...should be Last, First.'
        print 'You have done this %d time(s) already.Fixing input...'%count
        b[0]+=','
    d[b[0]]=b[1]
print 'The sorted list (by last name) is :'
for j in sorted(d.keys()):
    print j+' '+d[j]

8-12

import string
a=int(raw_input('start:'))
b=int(raw_input('end:'))
t=0
space='      '
flag=False
for i in range(a,b+1):
    if chr(i) in string.punctuation:
        flag=True
        t=i
        print 'DEC'+space+'BIN'+space+'OCT'+space+'HEX'+space+'ASCII'
        print '-'*70
        break
else:
    print 'DEC'+space+'BIN'+space+'OCT'+space+'HEX'
    print '-'*50

if flag==True:
    for j in range(a,t):
        print str(j)+space+'0'+bin(j)[2:]+space+oct(j)[1:]+space+hex(j)[2:]
    for k in range(t,b+1):
        print str(k)+space+'0'+bin(k)[2:]+space+oct(k)[1:]+space+hex(k)[2:]+space+chr(k)
else:
    for j in range(a,b+1):
        print str(j)+space+'0'+bin(j)[2:]+space+oct(j)[1:]+space+hex(j)[2:]

10.1信用卡交易系统

Carddata.txt
# carddata.txt
previous balance
25
debits
21.64
541.24
25
credits
-25
-541.24
finance charge/late fees
7.30
5
account log:
ignored:could not convert string to float: # carddata.txt
ignored:could not convert string to float: previous balance
data...processed
ignored:could not convert string to float: debits
data...processed
data...processed
data...processed
ignored:could not convert string to float: credits
data...processed
data...processed
ignored:could not convert string to float: finance charge/late fees
data...processed
data...processed
def safe_float(obj):
    'safe version of float()'
    try:
        retval = float(obj)
    except (TypeError,ValueError),diag:#检测是否为安全的浮点数,异常参数diag保存
        retval = str(diag)
    return retval#打印异常参数
def main():
    'handles all the data processing'
    log=open('cardlog.txt','w')#创建日志文件
    try:
        ccfile=open('carddata.txt','r')#监控:打开信用卡数据文件
    except IOError,e:
        log.write('no txns this month\n')#若遇到指定类型的异常,将异常信息写入日志
        log.close()#关闭日志文件
        return#结束程序运行
    txns=ccfile.readlines()#读取信用卡数据文件正常时,读取所有行保存到txns中
    ccfile.close()#关闭信用卡数据文件
    total=0.00
    log.write('account log:\n')#向日志文件写入信息

    for eachTxn in txns:#遍历txnsa列表
        result = safe_float(eachTxn)#用safe_float转换为浮点型,且监控指定异常
        if isinstance(result,float):#用内建isinstance函数检查结果类型是否float
            total+=result#result是float类型,加入运算
            log.write('data...processed\n')
        else:
            log.write('ignored:%s' %result)#不是float类型,写入日志
    print '$%.2f (new balance)' %(total)#打印最终处理结果
    log.close()#关闭日志文件

if __name__ == '__main__':#通常表明“仅在非导入时启动“
    main()

10.4with 语句:
with open('hhga.txt','r') as f:
    for eachLine in f:
        print eachLine

上下文

try:
    assert 1==0,'One does not equal zero silly!'
except AssertionError,args:
    print '%s:%s' %(args.__class__.__name__,args)
第十章练习
10-1
 d所有
10-3
 Try except finally else raise with assert
10-5
>>> if 3<4 then: print '3'
SyntaxError: invalid syntax
>>> x

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    x
NameError: name 'x' is not defined
>>> x=4%0

Traceback (most recent call last):
  File "<pyshell#8>", line 1, in <module>
    x=4%0
ZeroDivisionError: integer division or modulo by zero
>>> import math
>>> i=math.sqrt(-1)

Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    i=math.sqrt(-1)
ValueError: math domain error

10-6

def op(filename):
    try:
        f=open(filename,'r')
    except IOError:
        f=None
    return f
>>> op('hhga.txt')
<open file 'hhga.txt', mode 'r' at 0x028D50D0>
>>> for i in op('hhga.txt'):
    print i


The best way ……
>>> ======================== RESTART ========================
>>> 
>>> op('hhgf.txt')
>>> print op('hhgf.txt')
None

10-8

def safe_input():
    try:
        a=raw_input()
    except (EOFError,KeyboardInterrupt):
        return None

10-9没做出来不知道怎么在except里面运算传递值

def safe_sqrt(x):
    try:
        if
        import math
        y=math.sqrt(x)
        t=x
    except TypeError:
        import cmath
       y=cmath.sqrt(t)
    return y

11.1算术游戏easymath

#!/usr/bin/env python

from operator import add, sub
from random import randint, choice
#unix启动行,从operator和random模块中导入需要的函数
ops = {'+': add, '-': sub}#建立字典
MAXTRIES = 2#最大尝试次数

def doprob():
    op = choice('+-')#choice函数选择
from random import choice
a=choice(’01’)这时choice的语法。参数必须是只含有两个字符的字符串,返回只有其中一个字符的字符串。
    nums = [ randint(1,10) for i in range(2) ]#列表解析
#nums=[randint(1,10),randint(1,10)],也可。但是列表解析更易于扩展和升级。我们使用循环来代替剪切和粘贴也是这个原因。使用函数呢?
    nums.sort(reverse=True)#防止出现结果为负数的情况,从大到小排序
    ans = ops[op](*nums)#the appropriate operation function 合适运算函数
add(*[3,3])
    pr = '%d %s %d = ' % (nums[0], op, nums[1])
    oops = 0
    while True:#处理输入的控制循环
        try:#监控异常
            if int(raw_input(pr)) == ans:#输入与答案比较
                print 'correct'
                break
            if oops == MAXTRIES:#尝试达到三次,揭晓答案
                print 'sorry... the answer is\n%s%d' % (pr, ans)
            else:
                print 'incorrect... try again'#尝试错误,尝试次数增一
                oops += 1
        except (KeyboardInterrupt,
                EOFError, ValueError):#处理异常
            print 'invalid input... try again'

def main():
    while True:
        doprob()
        try:
            opt = raw_input('Again? [y] ').lower()#提示用户退出或进行下一个问题
            if opt and opt[0] == 'n':
                break
        except (KeyboardInterrupt, EOFError):
            break

if __name__ == '__main__':
    main()

使用装饰器的例子

Deco.py
from time import ctime,sleep #从time模块导入ctime,sleep 函数
def tsfunc(func):#定义装饰函数
    def wrappedFunc():#装饰函数内嵌函数
        print '[%s] %s() called' %(ctime(),func.__name__)#使得时间戳和函数名一起打印,用时间戳装饰函数。
        return func()
    return wrappedFunc
@tsfunc#装饰函数语法,在被装饰函数定义前一步进行装饰
def foo():
    pass

foo()
sleep(4)

for i in range(2):
    sleep(1)
    foo()
>>> 
[Thu Apr 09 19:59:44 2015] foo() called
[Thu Apr 09 19:59:49 2015] foo() called
[Thu Apr 09 19:59:50 2015] foo() called

11.3传递和调用(内建)函数(numConv.py)

#!/usr/bin/env python

def convert(func, seq):
    'conv. sequence of numbers to same type'
    return [func(eachNum) for eachNum in seq]

myseq = (123, 45.67, -6.2e8, 999999999L)
‘’’for i in [int ,long,float]:
    print [convert(i,myseq) for i in[int,long,float]]
’’’
print convert(int, myseq)
print convert(long, myseq)
print convert(float, myseq)


Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> def taxMe(cost,rate=0.0825):
    return cost+(cost*rate)

>>> taxMe(100)
108.25
>>> taxMe(100,0.05)
105.0
>>> def net_conn(host,port=80,stype='tcp'):
    print host+str(port)+stype


>>> net_conn('phaze',8000,'udp')
phaze8000udp
>>> net_conn('kappa')
kappa80tcp
>>> net_conn ('chino',stype='icmp')
chino80icmp
>>> 
>>> net_conn(stype='udp',host='solo')
solo80udp
>>> net_conn('deli',8080)
deli8080tcp
>>> net_conn(port=81,host='chino')
chino81tcp
>>> def taxMe2(rate=0.0825,cost):
    return cost*(1.0+rate)
SyntaxError: non-default argument follows default argument
>>> ======================== RESTART ========================
>>> 
>>> ======================== RESTART ========================
>>> 
>>> ======================== RESTART ========================
>>> 
>>> ======================== RESTART ========================
>>> 
>>> def tupleVarArgs(arg1,arg2='defaultB',*theRest):
    'display regular args and non-keyword variable args'
    print 'formal arg 1:',arg1
    print 'formal arg 2:',arg2
    for eachXtrArg in theRest:
        print 'another arg:',eachXtrArg


>>> tupleVarArgs('abc')
formal arg 1: abc
formal arg 2: defaultB
>>> tuple
<type 'tuple'>
a
>>> tuple
<type 'tuple'>
>>> tupleVarArgs(23,4.56)
formal arg 1: 23
formal arg 2: 4.56
>>> tupleVarArgs ('abc',123,'xyz',456.789)
formal arg 1: abc
formal arg 2: 123
another arg: xyz
another arg: 456.789
>>>

def dictVarArgs(arg1,arg2='defaultB',**theRest):
    'disp;ay 2 regular args and keyword variable args'
    print 'formal arg1:',arg1
    print 'formal arg2:',arg2
    for eachXtrArg in theRest.keys():
        print 'Xtra arg %s:%s'%(eachXtrArg,str(theRest[eachXtrArg]))

>>> dictVarArgs(1220,740.0,c='grail')
formal arg1: 1220
formal arg2: 740.0
Xtra arg c:grail
>>> dictVarArgs(arg2='tales',c=123,d='poe',arg1='mystery')
formal arg1: mystery
formal arg2: tales
Xtra arg c:123
Xtra arg d:poe
>>> dictVarArgs('one',d=10,e='zoo',men=('freud','gaudi'))
formal arg1: one
formal arg2: defaultB
Xtra arg men:('freud', 'gaudi')
Xtra arg e:zoo
Xtra arg d:10

>>> def newfoo(arg1,arg2,*nkw,**kw):
    'display regular args and all variable args'
    print 'arg1 is :',arg1
    print 'arg2 is :',arg2
    for eachNKW in nkw:
        print 'additional non-keyword arg:',eachNKW
    for eachKW in kw.keys():
        print "additional keyword arg '%s':%s" %(eachKW,kw[eachKW])


>>> newfoo('wolf',3,'projects',freud=90,gamble=96)
arg1 is : wolf
arg2 is : 3
additional non-keyword arg: projects
additional keyword arg 'gamble':96
additional keyword arg 'freud':90
>>>

>>> newfoo(10,20,30,40,f00=50,bar=60)
arg1 is : 10
arg2 is : 20
additional non-keyword arg: 30
additional non-keyword arg: 40
additional keyword arg 'bar':60
additional keyword arg 'f00':50
>>> newfoo(2,4,*(6,8),**{'foo':10,'bar':12})
arg1 is : 2
arg2 is : 4
additional non-keyword arg: 6
additional non-keyword arg: 8
additional keyword arg 'foo':10
additional keyword arg 'bar':12
>>> aTuple=(6,7,8)
>>> aDict={'z':9}
>>> newfoo(1,2,3,x=4,y=5,*aTuple,**aDict)
arg1 is : 1
arg2 is : 2
additional non-keyword arg: 3
additional non-keyword arg: 6
additional non-keyword arg: 7
additional non-keyword arg: 8
additional keyword arg 'y':5
additional keyword arg 'x':4
additional keyword arg 'z':9
>>>

10.5 testit测试函数

def testit(func,*nkwargs,**kwargs):#达到“把任意类型的任意个参数传递给任意函数对象”目标

    try:#监控异常
        retval = func(*nkwargs,**kwargs)
        result = (True,retval)#正常,打包运行结果
    except Exception,diag:
        result = (False,str(diag))#异常,打包异常参数diag
    return result

def test():
    funcs = (int, long , float)#函数元组
    vals = (123, 12,34, '1234', '12.34')#值元组
    for eachFunc in funcs:#迭代,每次拿出一个函数
        print '-'*20
        for eachVal in vals:#迭代,每次拿出一个值
            retval = testit(eachFunc,eachVal)#调用testit函数
            if retval[0]:#切片返回信息的首个元素,是否为真
                print '%s(%s) =' %(eachFunc.__name__, eachVal),retval[1]
            else:
                print '%s(%s) = FALLED:' %(eachFunc.__name__, eachVal),retval[1]

if __name__ == '__main__':
    test()
>>> ======================== RESTART ========================
>>> 
--------------------
int(123) = 123
int(12) = 12
int(34) = 34
int(1234) = 1234
int(12.34) = FALLED: invalid literal for int() with base 10: '12.34'
--------------------
long(123) = 123
long(12) = 12
long(34) = 34
long(1234) = 1234
long(12.34) = FALLED: invalid literal for long() with base 10: '12.34'
--------------------
float(123) = 123.0
float(12) = 12.0
float(34) = 34.0
float(1234) = 1234.0
float(12.34) = 12.34
>>>

Python函数式编程四个内建函数apply(),filter(),map(),reduce()
Filter()一个过滤函数、一个序列,返回序列中通过函数时值为真的新序列。

from random import randint
def odd(n):
    return n%2

allNums=[]
for eachNum in range(9):
    allNums.append(randint(1,99))
print filter(odd,allNums)


myseq=(123,45.67,-6.2e8,99999999L)

print [map(i,myseq) for i in[int,long,float]],

'''
from random import randint
def odd(n):
    return n%2

allNums=[]
for eachNum in range(9):
    allNums.append(randint(1,99))
print filter(odd,allNums)
'''
'''用lambda创建匿名函数更方便
from random import randint
allNums=[]
for eachNum in range(9):
    allNums.append(randint(1,99))
print filter(lambda n: n%2,allNums)
'''
'''用列表解析代替filter函数和lambda表达式
from random import randint
allNums=[]
for eachNum in range(9):
    allNums.append(randint(1,99))
print [n for n in allNums if n%2]
'''
'''
#更强大的列表解析
from random import randint as ri
print [n for n in [ri(1,99) for i in range(9)] if n%2]
'''

变量作用域:

>>> is_this_global='xyz'
>>> def foo():
    global is_this_global
    this_is_local='abc'
    is_this_global='def'
    print this_is_local + is_this_global


>>> print is_this_global
xyz
>>> foo()
abcdef
>>> print is_this_global
def
>>>

11.8变量作用域和名称空间

#!/usr/bin/env python
j, k = 1, 2

def proc1():

    j, k = 3, 4
    print "j == %d and k == %d" % (j, k)
    k = 5

def proc2():

    #global j
    j = 6
    proc1()
    print "j == %d and k == %d" % (j, k)

k = 7
proc1()
print "j == %d and k == %d" % (j, k)

j = 8
proc2()
print "j == %d and k == %d" % (j, k)
>>> 
j == 3 and k == 4
j == 1 and k == 7
j == 3 and k == 4
j == 6 and k == 7
j == 8 and k == 7
>>>

简单的生成器:

>>> from random import randint
>>> def randGen(aList):
    while len(aList)>0:
        yield aList.pop(randint(0,len(aList)))


>>> for i in randGen(['rock','paper','scissors']):
    print i


paper
rock
scissors

12.6模块内建函数

def foo():
    print '\ncalling foo()...'
    aString = 'bar'
    anInt = 42
    print "foo()'s globals:",globals().keys()
    print "foo()'s locals:",locals().keys()
print "__main__'s globals:",globals().keys()
print "__main__'s locals:",locals().keys()
foo()

>>> 
__main__'s globals: ['__builtins__', '__file__', '__package__', '__name__', 'foo', '__doc__']
__main__'s locals: ['__builtins__', '__file__', '__package__', '__name__', 'foo', '__doc__']

calling foo()...
foo()'s globals: ['__builtins__', '__file__', '__package__', '__name__', 'foo', '__doc__']
foo()'s locals: ['anInt', 'aString']
>>>

>>> mathObj=MyData()
>>> mathObj.x=4
>>> mathObj.y=5
>>> mathObj.x+mathObj.y
9
>>> mathObj.x*mathObj.y
20
>>> class MyDataWithMethod(object):
    def printFoo(self):
        print 'You invoked printFoo()!'


>>> myObj=MyDataWithMethod()
>>> myObj.printFoo()
You invoked printFoo()!
>>>

创建类

class AddrBookEntry(object):
    'address book entry class'
    def __init__(self,nm,ph):
        self.name=nm
        self.phone=ph
        print 'Created instance for:',self.name
    def updatePhone(self,newph):
        self.phone=newph
        print 'Updated phone#for:',self.name

实例化,查看实例属性与调用方法

>>> john=AddrBookEntry('John Doe','1111111')
Created instance for: John Doe
>>> jane=AddrBookEntry('Jane Doe','11212121221')
Created instance for: Jane Doe
>>> john
<__main__.AddrBookEntry object at 0x02C23ED0>
>>> john.name
'John Doe'
>>> john.phone
'1111111'
>>> jane.name
'Jane Doe'
>>> jane.phone
'11212121221'
>>> john.updatePhone('98989898')
Updated phone#for: John Doe
>>> john.phone
'98989898'
>>>
class I(object):
    count=3
    def __InIt__(self):
        I.count+=1
    def __del__(self):
        I.count-=1
    def howMany(self):
        return I.count

>>> a=I()
>>> b=I()
>>> a.howMany()
3
>>> b.howMany()
3
>>> del b
>>> a.howMany()
2
>>> a.__del__()
>>> a.howMany()
1
>>> del a
>>> I.count
0

带默认参数的实例化

class HotelRoomCalc(object):
    'Hotel room rate calculator'
    def __init__(self,rt,sales=0.085,rm=0.1):
        '''HotelRoomCalc default arguments
        sales tax==8.5% and room tax==10%'''
        self.salesTax=sales
        self.roomTax=rm
        self.roomRate=rt

    def calcTotal(self,days=1):
        'Calculate total;default to daily rate'
        daily = round((self.roomRate*(1+self.roomTax+self.salesTax)),2)
        return float(days)*daily

    >>> sfo=HotelRoomCalc(299)
>>> sfo.calcTotal()
354.31
>>> sfo.calcTotal(2)
708.62
>>> sea=HotelRoomCalc(189,0.086,0.058)
>>> sea.calcTotal()
216.22
>>> sea.calcTotal(4)
864.88
>>> wasWkDay=HotelRoomCalc(169,0.045,0.02)
>>> wasWkEnd=HotelRoomCalc(119,0.045,0.02)
>>> wasWkDay.calcTotal(5)+wasWkEnd.calcTotal()
1026.6299999999999

类中的静态方法:

>>> class TestStaticMethod:
    def foo():
        print 'calling static method foo()'
    foo=staticmethod(foo)


>>> a=TestStaticMethod()
>>> a.foo()
calling static method foo()
>>> TestStaticMethod.foo()
calling static method foo()

类中的类方法

>>> class TestClassMethod:
    def foo(cls):#必须传入一个类参数
        print 'calling class method foo()'
        print 'foo() is part of class:',cls.__name__
    foo=classmethod(foo)


>>> b=TestClassMethod()
>>> b.foo()
calling class method foo()
foo() is part of class: TestClassMethod
>>> TestClassMethod.foo()
calling class method foo()
foo() is part of class: TestClassMethod

在子类已经定义了和父类中同名的方法,此时还想调用父类的该方法:

>>> class C(P):
    def foo(self):
        P.foo(self)#传入子类的实例给父类,才能调用父类的未绑定方法
        print 'Hi,I am C--foo()'


>>> c=C()
>>> c.foo()
Hi,I am P-foo()
Hi,I am C--foo()

另一个方法:使用super()内建函数

>>> class C(P):
    def foo(self):
        super(C,self).foo()
        print 'Hi,Iam C-foo()'


>>> c=C()
>>> c.foo()
Hi,I am P-foo()
Hi,I am C-foo()
在举例:
>>> class P(object):#基类
    def __init__(self):
        print "calling P's constructor"


>>> class C(P):#子类
    def __init__(self):#定义了和基类中同名的方法
        print "calling C's constructor"


>>> c=C()
calling C's constructor
>>> c.__init__()#调用该方法,子类方法覆盖了基类的方法
calling C's constructor
>>> class C(P):
    def __init__(self):
        P.__init__(self)#使用子类实例(传入了实例名:self)调用基类的未绑定方法
        print "calling C's constructor"


>>> c=C()
calling P's constructor
calling C's constructor
>>> c.__init__()
calling P's constructor
calling C's constructor
>>> class C(P):
    def __init__(self):
        super(C,self).__init__()#使用super()内建函数达到更佳的效果
        print "calling C's constructor"


>>> c=C()
calling P's constructor
calling C's constructor
再举例:从标准类型中派生
>>> class RoundFloat(float):#从标准类型float中派生,定制一个对两位小数进行四舍五入的类
    def __new__(cls,val):
        return float.__new__(cls,round(val,2))#调用未绑定的父类—>类方法。所有__new__方法都是类方法,需要显示的传入类作为第一个参数。


>>> RoundFloat(1.5955)
1.6
>>> RoundFloat(1.5945)
1.59
>>> RoundFloat(-1.9955)
-2.0
>>> class RoundFloat(float):
    def __new__(cls,val):
        return super(RoundFloat,cls).__new__(cls,round(val,2))


>>> RoundFloat(1.5955)
1.6
>>> RoundFloat(1.5945)
1.59
>>> RoundFloat(-1.9955)
-2.0
>>>

class SortedKeyDict(dict):
    def keys(self):
        return sorted(super(SortedKeyDict,self).keys())
d=SortedKeyDict((('zheng-cai',67),('hui-jun',68),('xin-yi',2)))#三对括号
print 'By iterator:'.ljust(12),[key for key in d]
print 'By keys():'.ljust(12),d.keys()
>>> 
By iterator: ['zheng-cai', 'xin-yi', 'hui-jun']
By keys():   ['hui-jun', 'xin-yi', 'zheng-cai']
>>>

多重继承:

class P1:
    def foo(self):
        print 'called P1-foo()'

>>> class P2:
    def foo(self):
        print 'called P2-foo()'
    def bar(self):
        print 'called P2-bar()'


>>> class C1(P1,P2):
    pass

>>> class C2(P1,P2):
    def bar(self):
        print 'called C2-bar()'


>>> class GC(C1,C2):
    pass
>>> gc=GC()
>>> gc.foo()#GC->C1->P1
called P1-foo()
>>> gc.bar()#GC->C1->P1->P2
called P2-bar()
之上为经典类:遍历方法为深度优先。经典类没有MRO
>>> GC.__mro__

Traceback (most recent call last):
  File "<pyshell#234>", line 1, in <module>
    GC.__mro__
AttributeError: class GC has no attribute '__mro__' 

>>> class P1(object):
    def foo(self):
        print 'called P1-foo()'

>>> class P2(object):
    def foo(self):
        print 'called P2-foo()'
    def bar(self):
        print 'called P2-bar()'


>>> class C1(P1,P2):
    pass

>>> class C2(P1,P2):
    def bar(self):
        print 'called C2-bar()'
>>> class GC(C1,C2):
    pass

>>> gc=GC()
>>> gc.foo()
called P1-foo()

>>> gc.bar()
called C2-bar()
新式类mro是广度优先
>>> GC.__mro__
(<class '__main__.GC'>, <class '__main__.C1'>, <class '__main__.C2'>, <class '__main__.P1'>, <class '__main__.P2'>, <type 'object'>)


13.12.2 isinstance()
>>> class C1(object):
    pass

>>> class C2(object):
    pass

>>> c1=C1()
>>> c2=C2()
>>> isinstance(c1,C1)
True
>>> isinstance(c2,C1)
False
>>> isinstance(c1,C2)
False
>>> isinstance(c2,C2)
True
>>> isinstance(C2,c1)

Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    isinstance(C2,c1)
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types

>>> isinstance(4,int)
True
>>> isinstance(5.3,float)
True
>>> class myClass(object);
SyntaxError: invalid syntax
>>> class myClass(object):
    def __init__(self):
        self.foo=100


>>> myInst=myClass()
>>> hasattr(myInst,'foo')
True
>>> getattr(myInst,'foo')
100
>>> hasattr(myInst,'bar')
False
>>> getattr(myInst,'bar')

Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    getattr(myInst,'bar')
AttributeError: 'myClass' object has no attribute 'bar'
>>> getattr(c,'bar','oops!')

Traceback (most recent call last):
  File "<pyshell#30>", line 1, in <module>
    getattr(c,'bar','oops!')
NameError: name 'c' is not defined
>>> setattr(myInst,'bar','my attr')
>>> dir(myInst)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo']
>>> myInst.__dict__.keys()
['foo', 'bar']
>>> getattr(myInst,'bar')
'my attr'
>>> del(myInst,'foo')
SyntaxError: can't delete literal
>>> delattr(myInst,'foo')
>>> myInst.__dict__.keys()
['bar']
>>> hasattr(myInst,'foo')
False
>>>
13.12.6 vars()
>>> class C(object):
    pass

>>> c=C()
>>> c.foo=100
>>> c.bar='Python'
>>> c.__dict__
{'foo': 100, 'bar': 'Python'}
>>> vars(c)
{'foo': 100, 'bar': 'Python'}
>>>

13.13.1简单定制


>>> rfm=RoundFloatManual(42)
class RoundFloatManual(object):
    def __init__(self,val):
        assert isinstance(val,float),"Value must be a float!"
        self.value=round(val,2)

Traceback (most recent call last):
  File "<pyshell#49>", line 1, in <module>
    rfm=RoundFloatManual(42)
  File "D:\Python27\2-2.py", line 3, in __init__
    assert isinstance(val,float),"Value must be a float!"
AssertionError: Value must be a float!
>>> rfm=RoundFloatManual(4.2)
>>> rfm
<__main__.RoundFloatManual object at 0x02C10EB0>
>>> print rfm
<__main__.RoundFloatManual object at 0x02C10EB0>
>>>
有错时将无输出。
输入正确时,返回的是对象。我们想要的是返回值。
修改:
class RoundFloatManual(object):
    def __init__(self,val):
        assert isinstance(val,float),"Value must be a float!"
        self.value=round(val,2)
    def __str__(self):
        return str(self.value)#return ‘%f’ %self.value

>>> rfm=RoundFloatManual(5.5964)
>>> print rfm
5.6
>>> rfm=RoundFloatManual(5.59065)
>>> print rfm
5.59
>>>
加入对__repr__()的定制,实现 数据在解释器中转储(dump)对象时,不要是默认的对象符号。
使得__repr__()、__str__()输出一致。并且显示结果为两位小数。
class RoundFloatManual(object):
    def __init__(self,val):
        assert isinstance(val,float),"Value must be a float!"
        self.value=round(val,2)
    def __str__(self):
        return '%.2f' %self.value

    __repr__=__str__

>>> rfm=RoundFloatManual(5.59065)
>>> print rfm
5.59
>>> rfm=RoundFloatManual(4.5069)
>>> print rfm
4.51
>>> rfm=RoundFloatManual(4.5049)
>>> print rfm
4.50

最终代码见 roundFloat2.py

13.13.2数值定制,中级定制

class Time60(object):
    def __init__(self,hr,min):
        self.hr=hr
        self.min=min
    def __str__(self):#显示更加有意义的输出
        return '%d:%d' %(self.hr,self.min)
>>> mon=Time60(10,30)
>>> tue=Time60(11,15)
>>> print mon,tue
10:30 11:15
>>> mon + tue

Traceback (most recent call last):
  File "<pyshell#76>", line 1, in <module>
    mon + tue
TypeError: unsupported operand type(s) for +: 'Time60' and 'Time60'
>>>
加入加法,重载__add__():
class Time60(object):
    def __init__(self,hr,min):
        self.hr=hr
        self.min=min
    def __str__(self):
        return '%d:%d' %(self.hr,self.min)
    def __add__(self,other):
        return self.__class__(self.hr + other.hr,self.min + other.min)


>>> a=Time60(10,30)
>>> b=Time60(11,15)
>>> a+b
<__main__.Time60 object at 0x02956090>
>>> print a+b
21:45
>>>
>>> print a-b

Traceback (most recent call last):
  File "<pyshell#83>", line 1, in <module>
    print a-b
TypeError: unsupported operand type(s) for -: 'Time60' and 'Time60'
>>>
减法类似

实现原位加法——增量赋值,重载__iadd__():
class Time60(object):
    def __init__(self,hr,min):
        self.hr=hr
        self.min=min
    def __str__(self):
        return '%d:%d' %(self.hr,self.min)
    def __add__(self,other):
        return self.__class__(self.hr + other.hr,self.min + other.min)

    def __iadd__(self,other):
        self.hr += other.hr
        self.min += other.min
        return self

>>> a=Time60(10,30)
>>> b=Time60(11,15)
>>> id(a)
46284592
>>> a+=b
>>> print a
21:45
>>> id(a)
46284592
>>>
    问题:更对优化见练习,实现60进制等
>>> c=Time60(12,5)
>>> 
>>> print c
12:5
>>> d=Time60(8,45)
>>> print a+d
29:90
>>>

第一个例子是RandSeq CRANDom SEQuence的缩写)。我们给我们的类传入一个初始序列,然后让
用户通过next()去迭代(无穷)。
init方法执行前述的赋值操作。iter_()仅返回self这就是如何将一个对象声明为迭代器的方式,最后,调用nextn来得到迭代器中连续的值。这个迭代器唯一的亮点是它没有终点。
这个例子展示了一些我们可以用定制类迭代器来做的与众不同的事情。一个是无穷迭代。

from random import choice

class RandSeq(object):
    def __init__(self,seq):
        self.data = seq

    def __iter__(self):
        return self

    def next(self):
        return choice(self.data)
>>> for i in RandSeq(('rock','paper','scissors')):
    print i
…
…   
scissors
paper
rock
scissors
scissors
…
…

2.AnyIter
class AnyIter(object):
    def __init__(self,data,safe=False):
        self.safe=safe
        self.iter=iter(data)

    def __iter__(self):
        return self

    def next(self,howmany=1):
        retval=[]
        for eachItem in range(howmany):
            try:
                retval.append(self.iter.next())
            except StopIteration:
                if self.safe:
                    break
                else:
                    raise
        return retval

>>> a=AnyIter(range(10))
>>> i=iter(a)
>>> for j in range(1,5):
    print j,':',i.next(j)


1 : [0]
2 : [1, 2]
3 : [3, 4, 5]
4 : [6, 7, 8, 9]
>>> i
<__main__.AnyIter object at 0x02AF3F50>
>>> print i
<__main__.AnyIter object at 0x02AF3F50>
>>> i.next()

Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    i.next()
  File "D:\Python27\2-2.py", line 13, in next
    retval.append(self.iter.next())
StopIteration

>>> a=AnyIter(range(10))
>>> i=iter(a)
>>> i.next(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> i.next(11)

Traceback (most recent call last):
  File "<pyshell#12>", line 1, in <module>
    i.next(11)
  File "D:\Python27\2-2.py", line 13, in next
    retval.append(self.iter.next())
StopIteration
>>>

>>> b=AnyIter(range(10),True)
>>> j=iter(b)
>>> j.next(99)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> j.next(99)
[]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值