python运算符与表达式

1.1. 数值操作

所有数值类型都提供下列运算:

运算                    描述
x + y                   加
x - y                   减
x * y                   乘
x / y                   常规除
x // y                  地板除
x ** y                  乘方 (xy )
x % y                   取模 (x mod y )
-x                      改变操作数的符号位
+x                      什么也不做
~x                      ~x=-(x+1)

 

        关于常规除 / 与地板除 //: 地板除在任何时候都会将小数部分舍为0,而常规除的行为依操作数的类型而有不同。
        常规除 / : 整数除以整数时 / 与 // 除完全相同,商都会被舍去小数部分而返回一个整数。如7 / 4 的结果是 1,而不是1.75; 
        如果有一个操作数为浮点数,情形就不同了:
        对于 / ,会返回一个双精度浮点数
        对于 //,也会返回一个双精度浮点数,只不过小数部分被舍弃

取模操作返回 x/y 的余数,如7 % 4是3。对于浮点数,取模操作返回的是x – int(x / y ) * y。 对于复数,取模操作返回x – int((x / y ).real ) * y。

下列列出的位运算符只能用于整数或长整数:

操作                    描述
x << y                  左移
x >> y                  右移
x & y                   按位与
x | y                   按位或
x ^ y                   按位异或 (exclusive or)
~x                      按位翻转

这些都是相当原始的运算,操作的是操作数的每一个位。所有的操作数都假定是以二进制补码形式表示。对于长整数,按位运算符假定符号位可以被无限地向左扩展。

除了这些以外,下边这些内建函数支持所有的数值类型:

函数                    描述
abs(x )                 绝对值
divmod(x ,y )           返回 (int(x / y ), x % y )
pow(x ,y [,modulo ])    返回 (x ** y ) x % modulo
round(x ,[n])           四舍五入,n为小数点位数

abs()函数返回一个数的绝对值。divmod()函数返回一个包含商和余数的元组。pow()函数可以用于代替 ** 运算,但它还支持三重取模运算(经常用于密码运算)。 round函数总是返回一个浮点数。Python的四舍五入规则不是银行家四舍五入规则,这一点请大家注意。

下列比较操作有标准的数学解释,返回一个布尔值True,或者False:

运算符                  描述
x < y                   小于
x > y                   大于
x == y                  等于
x != y                  不等于(与<>相同)
x >= y                  大于等于
x <= y                  小于等于

Python的比较运算可以连结在一起,如w < x < y < z 。这个表达式等价于 w < x and x < y and y < z 。

x < y > z这个表达式也是合法的,(注意,这个表达式中 x 和 z 并没有比较操作)。不建议这样的写法,因为这会造成代码的阅读困难。

只可以对复数进行等于(==)及不等于(!=)比较,任何对复数进行其他比较的操作都会引发 TypeError异常。

数值操作要求操作数必须是同一类型,若Python发现操作数类型不一致,就会自动进行类型的强制转换,转换规则如下:

1.如果操作数中有一个是复数,另一个也将被转换为复数
2.如果操作数中有一个是浮点数,另一个将被转换为浮点数
3.如果操作数中有一个是长整数数,另一个将被转换为长整数数
4.如果以上都不符合,则这两个数字必然都是整数,不需进行强制转换。

 

1.2. 序列运算

序列支持以下操作:

操作                      描述
s + r                   序列连接
s * n , n * s           s的 n 次拷贝,n为整数
s % d                   字符串格式化(仅字符串)
s[i]                    索引
s[i :j ]                切片
x in s , x not in s     从属关系
for x in s :            迭代
len(s)                  长度
min(s)                  最小元素
max(s)                  最大元素

+ 运算符将两个相同类型的序列连结成一个。 s * n 运算符给出一个序列的 n 次浅拷贝。下边的例子可以帮助你理解这点:

Toggle line numbersToggle line numbers
   1 a = [3,4,5]        # 一个列表
   2 b = [a]            # 包含a的列表
   3 c = 4*b            # b的四次拷贝
   4 
   5 # 修改 a
   6 a[0] == -7
   7 
   8 # 打印出 c
   9 print c

程序将会输出:

[[-7, 4, 5], [-7, 4, 5], [-7, 4, 5], [-7, 4, 5]]

这种情况下,列表b中放置了到列表a的引用,当b被重复的时候,仅创建了4个额外的引用。所以,当a被修改的时候,这个变化也影响到所有a的引用。这种情况通常是大多程序员不愿意看到的。你可以通过复制a中的所有元素来解决这种问题。如:

a = [3, 4, 5 ]
c = [a[:] for j in range((4)]  # [:]代表a的副本而不是到a的引用

 

        注:a[:]这种方式也仅仅是创建列表a所有元素的浅拷贝,如果a中有元素为可变元素,仍然可能会有潜在问题。 --WeiZhong

标准库中的copy模块也可以用于一个对象的浅复制,另外它还支持深复制。

索引操作符 s[n] 返回序列中的第 n个对象(s[0]是第一个),如果 n 是负数,在求值之前,就先执行 n+=len(s)。如果尝试读取一个不存在的元素则会引发 IndexError异常。

切片操作符s[i:j]返回一个子序列。i 和 j 必须是整数或长整数。如果被省略,那么它们的默认值分别为序列的开始或结束。切片操作同样允许负数索引。你只要记住这个公式:s[n]=s[n-len (s)] (n为正数) 或者 s[n]=s[len(s)+n] (n为负数)就行了。

Toggle line numbersToggle line numbers
   1 s=[1,2,3,4]             # S 上界为 0 下界为 4 
   2 print s[-100:100]       #返回 [1,2,3,4] -100超出了上界,100超出了下界:等价于 s[0:4]
   3 print s[-100:-200]      #返回 [] -100,-200均超出了上界,自动取上界:等价于s[0:0]
   4 print s[100:200]        #返回 [] 100,200均超出了下界,自动取下界值:等价于s[4:4]

x in s 运算符检验对象 x 是否是 s 的子对象,并返回True或False。 not in 运算符刚好与 in 相反。for x in s 操作顺序迭代序列中的全部元素,这将在第五章–控制流中详细介绍。len(s)返回一个序列中的元素个数。 min(s)和max(s)返回一个序列的最小值和最大值,这两个函数只有序列中的元素可排序时返回值才有意义。(如果对一个文件对象的列表取最大值或最小值,就毫无意义)

字符串和元组是不可变对象,不能在创建之后对原始对象修改。列表则可以进行以下操作:

操作                      描述
s[i ] = x               为s[i]重新赋值
s[i :j ] = r            将列表片段重新赋值
del s[i ]               删除列表中一个元素
del s[i :j ]            删除列表中一个片段

s[i] = x操作将列表索引为 i 的元素重新赋值为对象 x ,并增加 x 的引用记数。如果i是负数,在求值之前,就先执行 i+=len(s),计算结果必须是一个小于len(s)的非负整数。尝试给一个不存在的索引赋值会引发 IndexError 异常. 切片分配操作符 s[i:j] = r 将列表片段s[i:j]替换为序列 r。如:

Toggle line numbersToggle line numbers
   1 a = [1,2,3,4,5]
   2 a[1] = 6            # a = [1,6,3,4,5]
   3 a[2:4] = [10,11]    # a = [1,6,10,11,5]
   4 a[3:4] = [-1,-2,-3] # a = [1,6,10,-1,-2,-3,5]
   5 a[2:] = [0]         # a = [1,6,0]

del s[i]语句从列表s中删除元素i,并将它的引用记数减1。del s[i:j]语句删除一个切片。

序列可以使用<, >, <=, >=, == 和 != 来进行比较。当比较两个序列的时候,首先比较序列的第一个元素。如果它们不同,就马上得出结论.如果它们相同,就继续比较第二个元素,直到找到两个不同的元素或者两个序列都没有多余元素为止。字符串通过比较每个字符的内部编码决定大小(如ASCII或Unicode)。

字符串取模运算 s % d 返回一个格式化后的字符串。 需要一个格式字符串 s 作为左操作数,一个独立对象或一个元组或一个映射对象 d 作为右操作数。格式字符串 s 可以是ASCII字符串,也可以是一个Unicode字符串。这个运算符和 C 语言中的 sprintf() 函数类似。格式字符串包含两种对象类型:普通字符(不改变它的值)和转换符 (% + 转换字符)— 在输出结果中,转换符将格式化 d 中的相应元素,然后用格式化后的结果填充自身。如果 s 内只有一个转换符,则允许一个 d 是一个独立的非tuple对象。否则 d 就必须是一个tuple或映射对象。如果 d 是一个tuple,则转换表示符的个数必须和d的长度相等;如果d是一个映射,每个转换表示符的 % 字符之后必须有一个小括号括起来的映射对象中的key值.表Table 4.1详细列出了转换符的使用.

表 4.1. 字符串格式转换

字符              输出格式
d,i             十进制整数或长整数
u               无符号十进制整数或长整数
o               八进制整数或长整数
x               十六进制整数或长整数
X               十六进制整数或长整数(大写字母)
f               浮点数如 [-]m.dddddd
e               浮点数如 [-]m .dddddde ±xx .
E               浮点数如 [-]m .ddddddE ±xx .
g,G             指数小于-4或者更高精确度使用 %e 或 %E; 否则,使用 %f
s               字符串或其他对象,使用str()来产生字符串
r               与 repr() 返回的字符串相同
c               单个字符
%               转换符标识 %

在 % 和转换字符串之间,允许出现以下修饰符,并且只能按以下顺序:

1.映射对象的 key,如果被格式化对象是一个映射对象却没有这个成分,会引发KeyError异常.
2.下面所列的一个或多个:
    左对齐标志
    +,数值指示必须包含
    0,指示一个零填充
3.指示最小栏宽的数字.转换值会被打印在指定了最小宽度的栏中并且填充在(或者右边).
4. 一个小数点用来分割浮点数
5. A number specifying the maximum number of characters to be printed from a string, the number of digits following the decimal point in a floating-point number, or the minimum number of digits for an integer.
另外,形标(*)字符用于在任意宽度的栏中代替数字. If present, the width will be read from the next item in the tuple.下边的代码给出了几个例子:

 

Toggle line numbersToggle line numbers
   1 a = 42
   2 b = 13.142783
   3 c = "hello"
   4 d = {'x':13, 'y':1.54321, 'z':'world'}
   5 e = 5628398123741234L
   6 
   7 print 'a is %d' % a             #  "a is 42"
   8 print '%10d %f' % (a,b)         #  " 42 13.142783"
   9 print '%+010d %E' % (a,b)       #  "+000000042 1.314278E+01"
  10 print '%(x)-10d %(y)0.3g' % d   #  "13         1.54"
  11 print '%0.4s %s' % (c, d['z'])  #  "hell world"
  12 print '%*.*f' % (5,3,b)         #  "13.143"
  13 print 'e = %d' % e              #  "e = 5628398123741234"

 

1.3. 字典的操作

字典用来在名字与对象之间建立映射。对一个字典可进行以下操作:

操作              描述
x = d[k ]       通过 key 访问字典元素
d [k ] = x      通过 key 对字典元素进行赋值
del d[k ]       通过 key 删除某个字典元素
len(d )         字典的元素个数

key 可以是任意不可变对象,如字符串,数字,和元组。另外,字典的关键字也可以是用逗号分隔的多个值。例如:

Toggle line numbersToggle line numbers
   1 d = {}
   2 d[1,2,3] = "foo"
   3 d[1,0,3] = "bar"

在这种情况下,关键字的值其实是一个元组,下面的代码和上面的代码作用是一样的:

d[(1,2,3)] = "foo"
d[(1,0,3)] = "bar"

 

1.4. 增量赋值语句

Python提供以下的增量赋值操作:

操作            等价表达式
x += y          x = x + y
x -= y          x = x - y
x *= y          x = x * y
x /= y          x = x / y
x **= y         x = x ** y
x %= y          x = x % y
x &= y          x = x & y
x |= y          x = x | y
x ^= y          x = x ^ y
x >>= y         x = x >> y
x <<= y         x = x << y

应用举例:

Toggle line numbersToggle line numbers
   1 a = 3
   2 a += 1                      # a = 4
   3 b = [1,2]
   4 b[1] += 10                  # b = [1, 12]
   5 c = "%s %s"
   6 c %= ("Douglas", "Adams")   # c = "Douglas Adams"

需要指出的是,增量赋值语句并不对对象进行原地修改,因此也不会改变对象的性质。x += y语句创建了一个值为x + y的新对象,并将这个对象赋给 x。用户自定义类可通过定义特殊方法重载增量赋值操作符.(参见第三章,类型和对象)

 

1.5. 属性(.)操作符

点(.)操作符用来访问一个对象的属性,例如:

Toggle line numbersToggle line numbers
   1 foo.x = 3
   2 print foo.y
   3 a = foo.bar(3,4,5)
   4 del foo.x

点操作符并不仅仅可以用于单个表达式,例如foo.y.a.b . 它还可以用于函数的中间结果,例如a = foo.bar(3,4,5).spam .属性可以使用del语句来删除,例如del foo.x .

 

1.6. 类型转换

经常对内建类型进行类型转换的需要。下列内建函数提供了显式的的类型转换操作:

函数                      描述
int(x [,base ])         将x转换为一个整数
long(x [,base ])        将x转换为一个长整数
float(x )               将x转换到一个浮点数
complex(real [,imag ])  创建一个复数
str(x )                 将对象 x 转换为字符串
repr(x )                将对象 x 转换为表达式字符串
eval(str )              用来计算在字符串中的有效Python表达式,并返回一个对象
tuple(s )               将序列 s 转换为一个元组
list(s )                将序列 s 转换为一个列表
chr(x )                 将一个整数转换为一个字符
unichr(x )              将一个整数转换为Unicode字符
ord(x )                 将一个字符转换为它的整数值
hex(x )                 将一个整数转换为一个十六进制字符串
oct(x )                 将一个整数转换为一个八进制字符串

repr(x)函数也可写为 x .注意str()函数和repr()函数返回的结果经常是不同的. repr()函数取得对象的表达式字符串表示,通常可以使用eval()函数来重新得到这个对象.而str()产生一个对象的简洁格式表示(用于 print语句). ord()函数返回字符在ascii或Unicode字符编码中的整数顺序值. chr()和unichr()函数将一个整数分别转换为ascii或Unicode字符.

将一个字符串转换为数字或其他对象,使用int(), long(),和 float()函数. eval()函数也可以将一个包含有效表达式的字符转换为一个对象,例如:

Toggle line numbersToggle line numbers
   1 a = int("34")             # a = 34
   2 b = long("0xfe76214", 16) # b = 266822164L (0xfe76214L)
   3 b = float("3.1415926")    # b = 3.1415926
   4 c = eval("3, 5, 6")       # c = (3,5,6)

 

1.7. Unicode字符串

在同一个程序中使用标准字符串和Unicode字符串会有一点点复杂.这是因为对字符串有太多种操作,包括字符串连结,比较,字典关键字查询,以及在函数中用做参数.

内建函数unicode(s [, encoding [,errors ]])可以把一个标准字符串转换为一个Unicode字符串.字符串方法u.encode([encoding [, errors ]])可以把一个Unicode字符串转换为一个标准字符串.这些转换操作需要特殊编码规则来指定16位Unicode字符串与标准8位字符来相互映射. 编码参数是一个由如下值组成的特定字符串:

值                               描述
'ascii'                         7-bit ASCII
'latin-1' or 'iso-8859-1'       ISO 8859-1 Latin-1
'utf-8'                         8-位可变长度编码
'utf-16'                        16-位可变长度编码(可能是 little endian或 big endian)
'utf-16-le'                     UTF-16, little-endian 编码
'utf-16-be'                     UTF-16, big-endian 编码
'unicode-escape'                与Unicode文字 u"string" 相同
'raw-unicode-escape'            与原始 Unicode文字 ur"string"相同

默认编码在site模块中设置,可以通过sys.getdefaultencoding()来读取.在多数情况下,默认编码是’ascii’,即就是 ASCII字符,它的值在区间[0x00,0x7f]内,直接映射到Unicode字符的[U+0000, U+007F].其他关于编码的内容在第九章–输入与输出.

当转换字符串时,如果有一个字符不能被转换,那么就会引起一个UnicodeError异常.比如,如果编码规则为’ascii’, Unicode字符U+1F28 就不能被转换,因为它的值太大. 同样地,字符串 “\xfc” 也不能被转换到Unicode,因为它也超出了ASCII字符范围. errors参数决定如何处理编码错误.它是一个包含下列值的字符串:

值                       描述
'strict'                编码错误时引起一个UnicodeError异常
'ignore'                忽略不可转换字符
'replace'               将不可转换字符用U+FFFD替代(Unicode中的U+FFFD 是标准字符串中的'?')

默认错误处理是 ‘strict’.

当标准字符串和Unicode字符串在表达式中混用时,标准字符串将被自动转换为Unicode字符串.例如:

Toggle line numbersToggle line numbers
   1 s = "hello"
   2 t = u"world"
   3 w = s + t          # w = unicode(s) + t

当一个字符串方法(第三章中讲到)中使用到Unicode字符串时,结果也将总是Unicode字符串,例如:

Toggle line numbersToggle line numbers
   1 a = "Hello World"
   2 b = a.replace("World", u"Bob")  # b = u"Hello Bob"

此外,即使使用replace()方法进行零替换(替换结果仍是原始字符串)时,结果仍然会是Unicode字符串.

如果一个Unicode字符串使用 % 操作符做格式字符串,所有参数在一开始都将强制转换为Unicode字符串,然后再根据格式规则连结在一起.如果一个Unicode对象被用做 % 操作符的一个参数,整个结果也将是Unicode字符串(Unicode对象被扩充),例如:

Toggle line numbersToggle line numbers
   1 c = "%s %s" % ("Hello", u"World") # c = "Hello " + u"World"
   2 d = u"%s %s" % ("Hello", "World") # d = u"Hello " + u"World"

当使用Unicode字符串时, str()和repr()函数会自动使用默认编码将Unicode字符串转换为标准字符串.对于一个Unicode字符串u, str(u)相当于u.encode(), repr(u)相当于u”%s” % repr(u.encode(‘unicode-escape’)).

另外,许多库和内建函数只能用于操作标准字符串, Unicode字符串将会被自动使用默认编码转换为标准字符串.如果转换不可执行,会引发UnicodeError异常.

标准字符串和Unicode字符串可以比较.在这种情况下,标准字符串首先会使用默认编码强制转换为Unicode字符串.这个规则在列表和字典元素的比较操作中也同样适用.例如 ‘x’ in [u’x’, u’y’, u’z’] 强制将’x’转换为Unicode,并返回True. 对于从属测试, ‘W’ in u’Hello World’ 也同理(‘W’被转换为Unicode).

当使用 hash() 函数计算哈希值时,标准字符串和Unicode字符串返回同一个值(当Unicode字符串只包含[U+0000, U+007F]中的字符时).这样就可以使标准字符串和Unicode字符串在用做字典关键字时可以互换(但条件还是Unicode字符串只包含[U+ 0000, U+007F]中的字符),例如:

Toggle line numbersToggle line numbers
   1 a = { }
   2 a[u"foo"] = 1234
   3 print a["foo"]        # Prints 1234

但是,应该注意在默认编码被改变为非acsii或者Unicode字符串包含非ASCII字符时,字典关键字不具有这种可以互换的行为.比如,如果’utf-8’被用做默认编码,字符串比较会返回相等,但哈希值不同:

#python 
a = u"M\u00fcller"       # Unicode字符串
b = "M\303\274ller"      # utf-8 编码格式的 a
print a == b             # Prints True
print hash(a)==hash(b)   # Prints False

 

        注意,上面的例子在python2.4中会引发异常.所以上面这些言论可能已经过时. --WeiZhong

 

1.8. 布尔表达式

and, or,和 not关键字可以组成布尔表达式.这些操作符的特性如下:

操作符             描述
x or y          如果 x 为假,返回 y ; 否则,返回 x
x and y         如果 x 为假,返回 x ; 否则,返回 y
not x           如果 x 为假,返回 True ; 否则,返回 False

当你使用一个表达式用来判断True 或 False时,任何非零的数字或非空列表,元组,字典,都返回True。零,None,以及空列表,元组,字典返回False. 布尔表达式从左至右进行计算,而且具有短路行为,也就是说只有需要时才会进行右边表达式的计算.例如表达式 a and b 只有当a为True时才计算b.

      注:  0 and 10/0 这样的表达式不会引发 除0错误,因为 10/0 这个表达式被短路了。 --WeiZhong

 

1.9. 对象的比较与身份

相等运算符 x== y 检验x和y的值是否相等.在比较列表或元组,只有当所有的元素都相等时这两个对象才是相等的.对于字典,只有当x和y有相同的关键字和相同的对应值时,才会返回相等.

身份运算符 x is y 和 x is not y 检验两个对象在内存中否指向同一个对象.通常情况下, x==y,但 x is not y.

比较操作也可以在两个不兼容的对象类型之间进行,比如一个文件和一个浮点数,不过返回的结果是任意的,这样的比较也没有任何意义.另外,比较两个不兼容的对象有可能会引发异常.

 

1.10. 运算优先级

Table 4.2列出了Python运算符的运算顺序(优先级).除乘方(**)外的所有运算符都是从左至右进行运算.表中靠前的运算符优先级要比后边的高些,也就是说,靠前的运算符在一个表达式中会先运算.(注:同一栏的运算符,如 x * y , x / y , x % y 有相同的优先级)

Table 4.2. 运算优先级 (由高到低)

运算                                      名称
--------------------------------------------------------------------
(...), [...], {...}                     创建元组,列表,字典
--------------------------------------------------------------------
`...`                                   字符串转换
--------------------------------------------------------------------
s[i ], s[i:j ],  .attr                  索引,切片,属性
--------------------------------------------------------------------
f(...)                                  函数调用s
--------------------------------------------------------------------
+x , -x , ~x                            一元运算符
--------------------------------------------------------------------
x ** y                                  乘方(从右至左运算)
--------------------------------------------------------------------
x * y , x / y , x % y                   乘,除,取模
--------------------------------------------------------------------
x + y , x - y                           加,减
--------------------------------------------------------------------
x << y , x >> y                         移位
--------------------------------------------------------------------
x & y                                   按位与
--------------------------------------------------------------------
x ^ y                                   按位异或
--------------------------------------------------------------------
x | y                                   按位或
--------------------------------------------------------------------
x < y , x <= y ,
x > y , x >= y ,
x == y , x != y                         比较,身份,序列成员检测
x <> y
x is y , x is not y
x in s , x not in s
--------------------------------------------------------------------
not x                                   逻辑非
--------------------------------------------------------------------
x and y                                 逻辑与
--------------------------------------------------------------------
x or y                                  逻辑或
--------------------------------------------------------------------
lambda args : expr                      lambda函数表达式
转自 http://blog.163.com/sea_haitao/blog/static/7756216200962753857568/

psyco 真的很神奇

测试代码
http://www.timestretch.com/FractalBenchmark.html#e7142f2f73f8eb4245f1b25aa6340470

没有使用 psyco 3.4 左右,生成 pyc 3.14 ,用了 psyco 0.34
真是太强大了,

freebsd 安装 psyco

cd /usr/ports/devel/py-psyco
make install clean

开启

import psyco
psyco.full()

freebsd下python程序打包工具 ── cx_Freeze

cx_Freeze是一个类似py2exe的工具,它们区别是py2exe是将python程序打包成windows下可以执行的exe文件的,而cx_Freeze则是将python程序打包为linux下可以直接执行的ELF格式的二进制可执行文件(看说明好像也能生成windows的可执行文件,号称跨平台)。
cx_Freeze的作用就是让你的python程序可以脱离python运行环境,在没有安装python的微型linux系统(例如cdlinux、tinycore等)里,方便地运行你的python程序。从功能上来说,也可以将其理解为一个python程序的编译器,将你的源码隐藏起来。

安装

cd /usr/ports/devel/cx_Freeze
make install clean

打包程序

cxfreeze 你的程序文件.py --target-dir dist

Python date测试

import datetime, calendar   
   
today = datetime.date.today()   
oneday = datetime.timedelta(days=1)   
   
# loop back to most recent Friday (could be today)   
# takes care of end of month and even leap years   
   
friday = today   
while friday.weekday() != calendar.FRIDAY:   
     friday -=oneday   
   
oneweek = datetime.timedelta(days=7)   
nextweek = today + oneweek   
nextyear = today.replace(year=today.year+1)   
   
print "Today (year-month-day) = ", today   
print "Most recent Friday = ", friday   
print "One week from today = ", nextweek   
print "One year from today = ", nextyear   
print "Current time = ", datetime.datetime.now().time() # just the time   
print "Lunchtime = ", datetime.time(12,00) #12:00:00   
   
print '-'*50   
   
# a typical birthday year, month, day   
birthday = datetime.date(1977,4,27)   
# three diffeerent ways to present a date   
# 1977-04-27   
print "Birthday format1: ", birthday   
# 04/27/77   
print "Birthday format2: ", birthday.strftime("%m/%d/%y")   
# 01Apr1977   
print "Birthday format3: ", birthday.strftime("%d %b %Y")   
   
age = today - birthday   
print "You are ", age.days, "days old today!"   
   
# extract the year from todays date   
thisyear = int(today.strftime("%Y")[0:4])   
   
# party message (include date and time)   
rightnow = datetime.datetime.today()   
bparty = datetime.datetime(thisyear, 4, 27, 14, 30)   
# check if you can still make it to the party ...   
if bparty > rightnow:   
    print "Birthday party", bparty   
else:   
    print "Mised this year's birthday party!"   
   
print '-'*50   
   
# calculate days till xmas of this year   
xmas = datetime.date(thisyear, 12, 25)   
tillXmas = xmas - today   
print "There aere %d days till xmas!" % tillXmas.days   
   
print '-'*50   
   
# add days to a given date   
delta = datetime.timedelta(days=77)   
addDays = today + delta   
print "Today 's date is               :", today.strftime("%d%b%Y")   
print "77 days from today it will be :", addDays.strftime("%d%b%Y")   
   
print '-'*50   
   
Weekday = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday',    
    'Saturday', 'Sunday']   
   
print "Today is ", Weekday[datetime.date.weekday(today)] 

转自 http://hi.baidu.com/10428/blog/item/d351fa364d2f11360b55a9f2.html

當Deferred遇上Thread

當Deferred遇上Thread
Deferred不會自動實現將阻塞過程轉為非阻塞過程,雖然它已經有那樣的機制但還是要你去多走一步。要將阻塞過程轉為真正的非阻塞過程,那 只有借用線程。但至於線程調用你不用太擔心,twisted已為你準備好一個方便的用法。就是將Deferred綁在Thread上,這樣就有了deferToThread,味道不比牛奶加巧克力差。
deferToThread在twisted文檔的說明,洋墨水喝得比較少,就不照字面翻譯了。大概意思是將函數f放在線程裡並作為Deferred返回,args和kwargs是函數f的參數。也就是使用deferToThread返回的是一個帶線程的Deferred,並自動使用callback調用指定的函數f。相當於在線程中運行下面的代碼
d=defer.Deferred().addCallback(f)
d.callback(result)

def deferToThread(f, *args, **kwargs): (source)
Run a function in a thread and return the result as a Deferred. Parameters f The function to call.

*args positional arguments to pass to f.

**kwargs keyword arguments to pass to f.
Returns A Deferred which fires a callback with the result of f, or an errback with a twisted.python.failure.Failure if f throws an exception.

#!/usr/bin/env python
#coding=utf-8

from twisted.internet import protocol,reactor,defer
from twisted.internet.threads import deferToThread
from twisted.protocols import basic
import time,sys
syscode='big5'

class muProtocol(basic.LineReceiver):

	def connectionMade(self):
		print 'connectionMade'
		self.factory.clients[self]={}
		self.factory.clients[self]['isblankly']=True

def lineReceived(self,data):
	self.factory.clients[self]['isblankly']=False
	self.transport.write(self.factory.getSomething(data))
	if data=='q':
		self.transport.loseConnection()
		self.factory.kungfuTea(data)

class muFactory(protocol.ServerFactory):
	protocol=muProtocol

	def __init__(self):
		reactor.callLater(1,self.timeout)
		self.clients={}

	def timeout(self):
		sys.stdout.write('.')
		sys.stdout.flush()
		reactor.callLater(1,self.timeout)

	def getSomething(self,data):
		return '\n\rServer say: %s\n\r' % data

	def goodTaste(self,data):
		print u'%s:耍下太極,仲加埋嘆下功夫茶,都有排等羅。'.encode(
		syscode,'replace') % data
		time.sleep(10)
		print u'%s,打完收功。'.encode(syscode,'replace') % data
		return data

	def wrongTaste(self,data):
		print u'%s:好味道盡在kung fu tea。'.encode(syscode,'replace') % data

	def kungfuTea(self,data):
		return deferToThread(self.goodTaste,data
		).addBoth(self.wrongTaste)

reactor.listenTCP(20190,muFactory())
reactor.run()

分析下上面的代碼。
當接收到數據後調用self.factory.kungfuTea(data)
def lineReceived(self,data):
self.factory.kungfuTea(data)
工廠中的kungfuTea只是使用deferToThread將真正處理數據的過程轉goodTaste為一個線程的Deferred,剩下的東西就和Deferred操作無異。

牛奶加巧克力不錯,老板再來一杯!

原文 http://sites.google.com/site/mypynotes/twisted-1/defertothread

Deferred筆記一

Deferred的簡單套路

從twisted的文檔入手,將Deferred獨立出來簡單的說明作用與使用方法,這樣更能快速對Deferred有深刻的了解。

一、學習資料
1、主要參考資料
官方文檔 http://twistedmatrix.com/projects/core/documentation/howto/deferredindepth.html
關聯譯文 http://wiki.woodpecker.org.cn/moin/twistedTUT00?action=AttachFile&do=get&target=deferred_tutorial.html(此鏈接將會下載離線文檔)

2、關聯資源
http://wiki.woodpecker.org.cn/moin/TwistedTUT

二、Deferred的作用
Deferred的主要作用可以用一句話比較形象說明,“不要打電話給我,我會打給你的(Don’t Call Us, We’ll Call You)”。相當於做好計劃後,執行交給Deferred,完成後再找我,我可要到一邊Happy去了。
它會根據callback運行結果(正常、發生例外)從callback鏈表中選擇執行已註冊的相應的callback函數,從而實現事件方式來驅動程序。
callback的運行不影響主程序的運行,Deferred.callback執行後馬上返回。(這點有待在後面證明)

三、Deferred實例
from twisted.internet import defer
d=defer.Deferred()
實例化後就可以對Deferred進行操作。

四、callback鏈表
鏈表是用來放置callback函數,鏈表中的函數可以響應三類事件,正常結束、例外結束、任意(包括前面兩者),它們分別用addCallback、addErrback、addBoth註冊到鏈表中。也就是說函數正常結束返回調用addCallback註冊的函數,發生例外則調用addErrback註冊的函數,使用addBoth註冊的函數無論返回什 結果都會被調用。

五、callback函數註冊
除了上面提過的addCallback、addErrback、addBoth三個註冊函數外,還有另外一個addCallbacks可以同時註冊處理正常結束和例外結束的函數。

1
2
3
4
5
6
def deferredExample():
d = defer.Deferred()
d.addCallback(failAtHandlingResult)
d.addCallbacks(yesDecision, noDecisionPassthru)
d.addCallback(handleResult) # – A –
d.addErrback(handleFailure)

上面代碼中第4行的addCallbacks效果如同
d.addCallback(yesDecision)
d.addErrback(noDecisionPassthru)

另外,我們也可以將註冊過程寫成下面形式。
d=refer.Deferred().addCallback(failAtHandlingResult).addCallbacks(yesDecision, noDecisionPassthru).addCallback(handleResult).addErrback(handleFailure)

六、callback鏈執行順序
Deferred的鏈表是按順序從第一個註冊函數開始直到最後一個函數。如果發生例外時,有多個例外處理函數,則會調用發生例外函數下面第一個例外處理函數。後面的例外處理函數將不會被調用,除非第一個例外處理函數將這個例外向下傳遞。

七、其它一些特性
Deferred實例中還有另外一些函數,如pause,unpause,setTimeout,timeoutCall,chainDeferred,這些將留作下一步的測試。
另外還沒涉及到的是Deferred上一級的defer庫中的函數及其它類的使用,從一些代碼看來這些函數將會進一步有利於Deferred的應用,但這也有待後面的進上步學習。

八、總結
經過Deferred are beautiful一節學習,了解Deferred的使用方法及其事件響應機制。

創建於2009年8月31日

原文
http://sites.google.com/site/mypynotes/twisted-1/deferred
可以被gw了

Python 语法运用

1.
u=[“a”,”b”,”c”]
l = [“name=%s” % user for user in u ]

结果: [“name=a”, “name=b”,”name=c”]

l ={“a”:1,”b”:2,”c”:3}
[k for k,v in l.items()]
结果: [“a”,”b”,”c”]

l ={“a”:1,”b”:2,”c”:3}
[“%s=%s” % (k,v) for k,v in l.items()]
[“a=1″,”b=2″,”c=3”]

2.lambda
lambda 是预代理,代替要生成方法的指针,我这样理解的

d.addCallback(lambda m: “status of %s : %s” % (msg,m))
d.addCallback(lambda m: self.msg(user,m))

3.文件的操作
这是方指的是txt文件操作
# 注意路径只能是 / 的方式处理, 打开的模式,你可以采用 help(file)的方式来查.
f = file(“c:/tmp/abc.txt”,”r”)
for line in f:
user,status = line.split(“:”,1)
user = user.strip()
status = status.strip()
print “%s=%s” % (user,status)

其中 line.split(“:”,1) 是折分串,以 : 区分

f.read()返回字符串内容

4.类的属性
注意类的属性与类的实例属性
class counter:
count = 0
myc = 0
def __init__(self):
self.__class__.count +=1
self.myc +=1

c=counter()
c.count
1
c.myc
1
b=counter()
b.count
2
b.myc
1

可以count是每建一个实例就增加.是类的属性

python的dict,set,list,tuple应用

字典(dict)
dict 用 {} 包围
dict.keys(),dict.values(),dict.items()
hash(obj)返回obj的哈希值,如果返回表示可以作为dict的key
del 或 dict.pop可以删除一个item,clear清除所有的内容
sorted(dict)可以吧dict排序
dict.get()可以查找没存在的key,dict.[]不可以
dict.setdefault() 检查字典中是否含有某键。 如果字典中这个键存在,你可以取到它的值。 如果所找的键在字典中不存在,你可以给这个键赋默认值并返回此值。
{}.fromkeys()创建一个dict,例如: {}.fromkeys((‘love’, ‘honor’), True) =>{‘love’: True, ‘honor’: True}
不允许一个键对应多个值
键值必须是哈希的,用hash()测试
一个对象,如果实现_hash()_方法可以作为键值使用
集合(set)
集合是一个数学概念,用set()创建
set.add(),set.update.set.remove,添加更新删除,-= 可以做set减法
set.discard 和 set.remove不同在于如果删除的元素不在集合内,discard不报错,remove 报错
< <= 表示 子集,> >=表示超集
| 表示联合 & 表示交集 – 表示差集 ^ 差分集里啊
列表(list)
列表是序列对象,可包含任意的Python数据信息,如字符串、数字、列表、元组等。列表的数据是可变的,我们可通过对象方法对列表中的数据进行增加、修改、删除等操作。可以通过list(seq)函数把一个序列类型转换成一个列表。
append(x) 在列表尾部追加单个对象x。使用多个参数会引起异常。
count(x) 返回对象x在列表中出现的次数。
extend(L) 将列表L中的表项添加到列表中。返回None。
Index(x) 返回列表中匹配对象x的第一个列表项的索引。无匹配元素时产生异常。
insert(i,x) 在索引为i的元素前插入对象x。如list.insert(0,x)在第一项前插入对象。返回None。
pop(x) 删除列表中索引为x的表项,并返回该表项的值。若未指定索引,pop返回列表最后一项。
remove(x) 删除列表中匹配对象x的第一个元素。匹配元素时产生异常。返回None。
reverse() 颠倒列表元素的顺序。
sort() 对列表排序,返回none。bisect模块可用于排序列表项的添加和删除。
元组(tuple)
tuple=(1,),这是单个元素的元组表示,需加额外的逗号。
tuple=1,2,3,4,这也可以是一个元组,在不使用圆括号而不会导致混淆时,Python允许不使用圆括号的元组。
和列表一样,可对元组进行索引、分片、连接和重复。也可用len()求元组长度。
元组的索引用tuple[i]的形式,而不是tuple(i)。
和列表类似,使用tuple(seq)可把其它序列类型转换成元组。

Deferred Object In Twisted

Twisted uses the Deferred object to manage the callback sequence. The client application attaches a series of functions to the deferred to be called in order when the results of the asychronous request are available(this series of functions is known as a series of callbacks, or a callback chain), together with a series of functions to be called if there is an error in the asychronous request(known as a series of errbacks or an errback chain). The asychronous library code calls the first callback when the result is available, or the first errback when an error occurs, and the Deferred object then hands the results of each callback or errback function to the next function in the chain.

The Problem that Deferreds Solve

It is the second class of concurrency problem – non-computationally intensive tasks that involve an appreciable delay – that Deferreds are designed to help solve. Functions that wait on hard drive access, database access, and network access all fall into this class, although the time delay varies.

Deferreds are designed to enable Twisted programs to wait for data without hanging until that data arrives. They do this by giving a simple management interface for callbacks to libraries and applications. Libraries know that they always make their results available by calling Deferred.callback and error by calling Deferred.errback. Applications set up result handlers by attaching callbacks and errbacks to deferreds in the order they want them called.

The basic idea behind Deferreds, and other solutions to this problem, is to keep the CPU as active as possible. If one task is waiting on data, rather than have the CPU(and the program!) idle waiting for that data(a process normally called “blocking”), the program performs other operations in the meantime, and waits for some singnal that data is ready to be processed before returning to that process.

In Twisted, a function signals to the calling function that it is waiting by returning a Deferred. When the data is available, the program activeates the callbacks on that Deferred to process the data.

Deferreds – a signal that data is yet to come

In our email sending example above, a parent functions calls a function to connect to the remote server. Asynchrony requires that this connection function return without waiting for the result so that the parent function can do other things. So how does the parent function or its controlling program know that the connection doesn’t exist yet, and how does it use the connection once it does exist?

Twisted has an object that signals this situation. When the connection function returns, it signals that the operation is imcomplete by returning a twisted.internet.defer.Deferred object.

The Deferred has two purposes. The first is that it says “I am a signal that the result of whatever you wanted me to do is still pending.”. The second is that you can ask the Deferred to run things when the data does arrive.

Callbacks

The way you tell a Deferred what to do with the data once it arrives is by adding a callback – asking the Deferred to call a function once the data arrives.

One Twisted library function that returns a Deferred is twisted.web.client.getPage. In this example, we call getPage, which returns a Deferred, and we attach a callback to handle the contents of the page once the data is available:

Python代码

from twisted.web.client import getPage   
from twisted.internet import reactor   
  
def printContents(contents):   
    '''''  
    This is the 'callback' function, added to the Deferred and called by it when the promised data is available  
    '''  
  
    print "The Deferred has called printContents with the following contents:"  
    print contents    
  
    #Stop the Twisted event handling system -- this is usually handled   
    #in higher lever ways   
  
    reactor.stop()    
  
   #call getPage, which returns immediately with a Deferred, promissing to   
   #pass the page contents onto our callbacks when the contents are available   
  
deferred = getPage('http://www.google.com')   
  
#added a callback to the deferred -- request that it run printContents when   
#the page content has been downloaded   
  
deferred.addCallback(printContents)   
  
#Begin the Twisted event handling system to manage the process -- again   
# this isn't the usual way to do this   
  
reactor.run()  

from twisted.web.client import getPage
from twisted.internet import reactor

def printContents(contents):
    '''
    This is the 'callback' function, added to the Deferred and called by it when the promised data is available
    '''

    print "The Deferred has called printContents with the following contents:"
    print contents 

    #Stop the Twisted event handling system -- this is usually handled
    #in higher lever ways

    reactor.stop() 

   #call getPage, which returns immediately with a Deferred, promissing to
   #pass the page contents onto our callbacks when the contents are available

deferred = getPage('http://www.google.com')

#added a callback to the deferred -- request that it run printContents when
#the page content has been downloaded

deferred.addCallback(printContents)

#Begin the Twisted event handling system to manage the process -- again
# this isn't the usual way to do this

reactor.run()

A very common use of Deferreds is to attach two callbacks. The result of the first callback is passed to the second callback:

Python代码

from twisted.web.client import getPage   
from twisted.internet import reactor   
  
def lowerCaseContents(contents):   
     '''''  
     This is a 'callback' function, added to the Deferred and called by  
     it when the promised data is available. It converts all the data to lower  
     case.  
     '''  
  
     return contents.lower()   
  
def printContents(contents):   
  
    '''''  
    This a 'callback' function, added to the Deferred after lowerCaseContents  
    and called by it with the results of lowerCaseContents  
    '''  
    print contents   
    reactor.stop()   
  
deferred = getPage('http://www.google.com')   
  
#add two callbacks to the deferred -- request that it run lowerCaseContents   
#when the page content has been downloaded, and then run printContents with   
#the result of lowerCaseContents   
  
deferred.addCallback(lowerCaseContents)   
  
deferred.addCallback(printContents)   
  
reactor.run() 
from twisted.web.client import getPage
from twisted.internet import reactor

def lowerCaseContents(contents):
     '''
     This is a 'callback' function, added to the Deferred and called by
     it when the promised data is available. It converts all the data to lower
     case.
     '''

     return contents.lower()

def printContents(contents):

    '''
    This a 'callback' function, added to the Deferred after lowerCaseContents
    and called by it with the results of lowerCaseContents
    '''
    print contents
    reactor.stop()

deferred = getPage('http://www.google.com')

#add two callbacks to the deferred -- request that it run lowerCaseContents
#when the page content has been downloaded, and then run printContents with
#the result of lowerCaseContents

deferred.addCallback(lowerCaseContents)

deferred.addCallback(printContents)

reactor.run()

Error handling: errbacks

Just as a asynchronous function returns before its result is available, it may also return before it is possible to detect errors: failed connections, erroneous data, protocol errors, and so on. Just as you can add callbacks to a Deferred which it calls when the data you are expecting is available, you can add error handlers(errbacks) to a Deferred for it to call when an error occurs and it cannot obtain the data:

Python代码

from twisted.web.client import getPage   
from twisted.internet import reactor   
  
def errorHandler(err):   
    '''''  
    This is an 'errback' function, added to the Deferred which will call it in   
    the event of an error  
     '''  
    #this isn't a very effective handling of the error, we just print it out:   
    
    print "An error has occurred: <%s>" % str(err)   
    #and then we stop the entire process:   
    reactor.stop()   
  
def printContents(contents):   
    '''''  
    This is a 'callback' function, added to the Deferred and called by it which   
    the page content  
    '''  
    print contents   
    reactor.stop()   
  
#we request a page which doesn't exist in order to demonstrate the   
#error chain   
  
deferred = getPage("http://www.google.com/does-not-exits")   
  
#add the callback to the Deferred to handle the page content   
  
deferred.addCallback(printContents)   
  
#add the errback to the Deferred to handle any errors   
  
deferred.addErrback(errorHandler)   
  
reactor.run()  

by blog http://huangro.javaeye.com/blog/365988

Python 类型

1.Dictionry {} 相录于一个 key value的内容

mys={“a”:1,”b”:2,”c”:3}
mys[“a”] = 1
mys.keys()
mys.values()

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

2.List 是一个列表 []
mys=[“a”,”b”,1]
mys[0]
mys[1]
mys[-1]

for v in mys:
print v;

3. Tuple 一个不能改变的list ()
mys=(1,2,”a”)
mys[0]
mys[1]

for v in mys:
print v;

这三种类型可以完全结合
mys=[(2,3),(4,5),(“a”,”b”)]
mys={“a”:[2,3,4],”b”:[3,4,5]}
mys[“a”].pop() 可以这样的写。