ch11赋值,表达式和打印(python)


#序列赋值
>>> nudge = 1
>>> wink  = 2
>>> A, B = nudge, wink             # Tuple assignment
>>> A, B                           # Like A = nudge; B = wink
(1, 2)
>>> [C, D] = [nudge, wink]         # List assignment
>>> C, D
(1, 2)


#交换两数
>>> nudge = 1
>>> wink  = 2
>>> nudge, wink = wink, nudge      # Tuples: swaps values
>>> nudge, wink                    # Like T = nudge; nudge = wink; wink = T
(2, 1)


#通用化,赋值语句右边只要是任何可迭代的对象即可
>>> [a, b, c] = (1, 2, 3)          # Assign tuple of values to list of names
>>> a, c
(1, 3)
>>> (a, b, c) = "ABC"              # Assign string of characters to tuple
>>> a, c
('A', 'C')


#赋值语句的左右两边数量必须一致
>>> string = 'SPAM'
>>> a, b, c, d = string                            # Same number on both sides
>>> a, d
('S', 'M')

>>> a, b, c = string                               # Error if not
...error text omitted...
ValueError: too many values to unpack


#利用分片让左右两边数量一致
>>> a, b, c = string[0], string[1], string[2:]     # Index and slice
>>> a, b, c
('S', 'P', 'AM')

>>> a, b, c = list(string[:2]) + [string[2:]]      # Slice and concatenate
>>> a, b, c
('S', 'P', 'AM')

>>> a, b = string[:2]                              # Same, but simpler
>>> c = string[2:]
>>> a, b, c
('S', 'P', 'AM')

>>> (a, b), c = string[:2], string[2:]             # Nested sequences
>>> a, b, c
('S', 'P', 'AM')


#左边对象的序列嵌套的形状必须符合右边对象的形状
>>> ((a, b), c) = ('SP', 'AM')                     # Paired by shape and position
>>> a, b, c
('S', 'P', 'AM')


#for循环中的赋值
for (a, b, c) in [(1, 2, 3), (4, 5, 6)]: ...?         # Simple tuple assignment

for ((a, b), c) in [((1, 2), 3), ((4, 5), 6)]: ...?   # Nested tuple assignment

#函数中的赋值
def f(((a, b), c)):              # For arguments too in Python 2.6, but not 3.0
f(((1, 2), 3))

#序列解包
>>> red, green, blue = range(3)
>>> red, blue
(0, 2)

>>> range(3)                             # Use list(range(3)) in Python 3.0
[0, 1, 2]


#例子:分割序列
>>> L = [1, 2, 3, 4]
>>> while L:
...     front, L = L[0], L[1:]           # See next section for 3.0 alternative
...     print(front, L)
...
1 [2, 3, 4]
2 [3, 4]
3 [4]
4 []


#扩展的序列解包
C:\misc> c:\python30\python
>>> seq = [1, 2, 3, 4]
>>> a, b, c, d = seq
>>> print(a, b, c, d)
1 2 3 4

>>> a, b = seq  #两边的个数不一样
ValueError: too many values to unpack


#扩展的序列解包
>>> a, *b = seq
>>> a
1
>>> b
[2, 3, 4]



>>> *a, b = seq
>>> a
[1, 2, 3]
>>> b
4



>>> a, *b, c = seq
>>> a
1
>>> b
[2, 3]
>>> c
4



>>> a, b, *c = seq
>>> a
1
>>> b
2
>>> c
[3, 4]


#扩展的序列解包对于任何序列类型都有效,字符串也有效
>>> a, *b = 'spam'
>>> a, b
('s', ['p', 'a', 'm'])

>>> a, *b, c = 'spam'
>>> a, b, c
('s', ['p', 'a'], 'm')



>>> S = 'spam'

>>> S[0], S[1:]       # Slices are type-specific, * assignment always returns a list
('s', 'pam')

>>> S[0], S[1:3], S[3]   
('s', 'pa', 'm')


#扩展的序列解包改写上面的例子
>>> L = [1, 2, 3, 4]
>>> while L:
...     front, *L = L                    # Get first, rest without slicing
...     print(front, L)
...
1 [2, 3, 4]
2 [3, 4]
3 [4]
4 []



>>> seq
[1, 2, 3, 4]

>>> a, b, c, *d = seq  #d中虽然只有一个元素,但也是列表
>>> print(a, b, c, d)
1 2 3 [4]


#*号没有匹配的情况,e是空列表
>>> a, b, c, d, *e = seq
>>> print(a, b, c, d, e)
1 2 3 4 []

>>> a, b, *e, c, d = seq
>>> print(a, b, c, d, e)
1 2 3 4 []



>>> a, *b, c, *d = seq  #多个*号,出错
SyntaxError: two starred expressions in assignment

>>> a, b = seq   #没有*号,两边的个数又不同,出错
ValueError: too many values to unpack

>>> *a = seq  #单个*号,会出错
SyntaxError: starred assignment target must be in a list or tuple

>>> *a, = seq
>>> a
[1, 2, 3, 4]


#扩展的序列解包和分片赋值的对比
>>> seq
[1, 2, 3, 4]

>>> a, *b = seq                        # First, rest
>>> a, b
(1, [2, 3, 4])

>>> a, b = seq[0], seq[1:]             # First, rest: traditional
>>> a, b
(1, [2, 3, 4])



>>> *a, b = seq                        # Rest, last
>>> a, b
([1, 2, 3], 4)

>>> a, b = seq[:-1], seq[-1]           # Rest, last: traditional
>>> a, b
([1, 2, 3], 4)


#扩展的序列解包应用于for循环
for (a, *b, c) in [(1, 2, 3, 4), (5, 6, 7, 8)]:
    ...

a, *b, c = (1, 2, 3, 4)                            # b gets [2, 3]

for (a, b, c) in [(1, 2, 3), (4, 5, 6)]:           # a, b, c = (1, 2, 3), ...

for all in [(1, 2, 3, 4), (5, 6, 7, 8)]:
    a, b, c = all[0], all[1:3], all[3]


#多目标赋值语句
>>> a = b = c = 'spam'
>>> a, b, c
('spam', 'spam', 'spam')



>>> c = 'spam'
>>> b = c
>>> a = b


#多目标赋值语句和不可变对象
>>> a = b = 0
>>> b = b + 1
>>> a, b
(0, 1)


#多目标赋值语句和可变对象
>>> a = b = []
>>> b.append(42)
>>> a, b
([42], [42])



>>> a = []
>>> b = []
>>> b.append(42)
>>> a, b
([], [42])


#增强赋值语句
>>> x = 1
>>> x = x + 1                   # Traditional
>>> x
2
>>> x += 1                      # Augmented
>>> x
3


#增强赋值用于字符串实际是合并
>>> S = "spam"
>>> S += "SPAM"                 # Implied concatenation
>>> S
'spamSPAM'


#这里的合并会创建一个新的对象,这里把L的值复制到新对象中,[3]中的值也复制到新对象中
>>> L = [1, 2]
>>> L = L + [3]                 # Concatenate: slower
>>> L
[1, 2, 3]
>>> L.append(4)                 # Faster, but in-place
>>> L
[1, 2, 3, 4]



>>> L = L + [5, 6]              # Concatenate: slower
>>> L
[1, 2, 3, 4, 5, 6]
>>> L.extend([7, 8])            # Faster, but in-place
>>> L
[1, 2, 3, 4, 5, 6, 7, 8]


#+=的合并运算会被python映射为L.extend([9,10])
>>> L += [9, 10]                # Mapped to L.extend([9, 10])
>>> L
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


#因为+会创建新的对象
>>> L = [1, 2]
>>> M = L                       # L and M reference the same object
>>> L = L + [3, 4]              # Concatenation makes a new object
>>> L, M                        # Changes L but not M
([1, 2, 3, 4], [1, 2])

#+=就是原处增加元素
>>> L = [1, 2]
>>> M = L
>>> L += [3, 4]                 # But += really means extend
>>> L, M                        # M sees the in-place change too!
([1, 2, 3, 4], [1, 2, 3, 4])


#变量的命名规则
下划线或字母开头
区分大小写
禁止使用保留字

_X 不会被 form module import *导入
__X__是系统定义的变量
__X是类定义的本地"压缩"变量
_ 交互模式下的最后一个表达式的结果




#变量名没有类型,对象才有类型
>>> x = 0               # x bound to an integer object
>>> x = "Hello"         # Now it's a string
>>> x = [1, 2, 3]       # And now it's a list

#变量有作用域

#python PEB 8



#print函数返回None
>>> x = print('spam')         # print is a function call expression in 3.0
spam
>>> print(x)                  # But it is coded as an expression statement
None


#表达式和在原处的修改
>>> L = [1, 2]
>>> L.append(3)               # Append is an in-place change
>>> L
[1, 2, 3]

#丢失列表
>>> L = L.append(4)           # But append returns None, not L
>>> print(L)                  # So we lose our list!
None


#打印操作

#python中打印与文件和流的概念紧密相连

#文件对象的方法

#标准输出流 sys.stdout,标准输入流 sys.stdin,标准错误流 sys.stderr,脚本启动的时候创建的

#Python3,print是函数,python2.X是语句

#python3中的print函数
#print调用形式:
print(value,..., sep='',end='\n',file=sys.stdout,flush=False)
sep,end,file,flush 通过关键字参数传递
内部实现是调用str函数

#print函数的应用
C:\misc> c:\python30\python
>>>
>>> print()                                      # Display a blank line

>>> x = 'spam'
>>> y = 99
>>> z = ['eggs']
>>>
>>> print(x, y, z)                               # Print 3 objects per defaults
spam 99 ['eggs']


#定制sep
>>> print(x, y, z, sep='')                       # Suppress separator
spam99['eggs']
>>>
>>> print(x, y, z, sep=', ')                     # Custom separator
spam, 99, ['eggs']


#定制print函数的end
>>> print(x, y, z, end='')                        # Suppress line break
spam 99 ['eggs']>>>
>>>
>>> print(x, y, z, end=''); print(x, y, z)        # Two prints, same output line
spam 99 ['eggs']spam 99 ['eggs']
>>> print(x, y, z, end='...\n')                   # Custom line end
spam 99 ['eggs']...
>>>


#组合关键词参数
>>> print(x, y, z, sep='...', end='!\n')          # Multiple keywords
spam...99...['eggs']!
>>> print(x, y, z, end='!\n', sep='...')          # Order doesn't matter
spam...99...['eggs']!


#定制print函数的file参数
>>> print(x, y, z, sep='...', file=open('data.txt', 'w'))      # Print to a file
>>> print(x, y, z)                                             # Back to stdout
spam 99 ['eggs']
>>> print(open('data.txt').read())                             # Display file text
spam...99...['eggs']


#构建字符串
>>> text = '%s: %-.4f, %05d' % ('Result', 3.14159, 42)
>>> print(text)
Resulprint(X, Y)                            # Or, in 2.6: print X, Yt: 3.1416, 00042
>>> print('%s: %-.4f, %05d' % ('Result', 3.14159, 42))
Result: 3.1416, 00042


#python 2.6  print语句

#print语句的使用
C:\misc> c:\python26\python
>>>
>>> x = 'a'
>>> y = 'b'
>>> print x, y
a b


>>> print x, y,; print x, y
a b a b


>>> print x + y
ab
>>> print '%s...%s' % (x, y)
a...b


#打印流重定向
>>> print('hello world')               # Print a string object in 3.0
hello world

>>> print 'hello world'                # Print a string object in 2.6
hello world

>>> 'hello world'                      # Interactive echoes
'hello world'

#print语句的本质:提供了对如下的封装
>>> import sys                         # Printing the hard way
>>> sys.stdout.write('hello world\n')
hello world


#重定向输出流

print(X, Y)                            # Or, in 2.6: print X, Y
#下面的两行就是上面的print函数的本质
import sys
sys.stdout.write(str(X) + ' ' + str(Y) + '\n')

#重定向标准输出流到打开的文件中
import sys
sys.stdout = open('log.txt', 'a')       # Redirects prints to a file
...
print(x, y, x)                          # Shows up in log.txt


#自动化重定向流
C:\misc> c:\python30\python
>>> import sys
>>> temp = sys.stdout                   # Save for restoring later
>>> sys.stdout = open('log.txt', 'a')   # Redirect prints to a file
>>> print('spam')                       # Prints go to file, not here
>>> print(1, 2, 3)
>>> sys.stdout.close()                  # Flush output to disk
>>> sys.stdout = temp                   # Restore original stream

>>> print('back here')                  # Prints show up here again
back here
>>> print(open('log.txt').read())       # Result of earlier prints
spam
1 2 3


#python3中print函数的file参数
log =  open('log.txt', 'a')             # 3.0
print(x, y, z, file=log)                # Print to a file-like object
print(a, b, c)                          # Print to original stdout

#python2.6使用>>重定向
log =  open('log.txt', 'a')             # 2.6
print >> log, x, y, z                   # Print to a file-like object
print a, b, c                           # Print to original stdout


#
C:\misc> c:\python30\python
>>> log = open('log.txt', 'w')
>>> print(1, 2, 3, file=log)            # 2.6: print >> log, 1, 2, 3
>>> print(4, 5, 6, file=log)
>>> log.close()
>>> print(7, 8, 9)                      # 2.6: print 7, 8, 9
7 8 9
>>> print(open('log.txt').read())
1 2 3
4 5 6


#sys.stderr 标准错误
>>> import sys
>>> sys.stderr.write(('Bad!' * 8) + '\n')
Bad!Bad!Bad!Bad!Bad!Bad!Bad!Bad!

>>> print('Bad!' * 8, file=sys.stderr)     # 2.6: print >> sys.stderr, 'Bad' * 8
Bad!Bad!Bad!Bad!Bad!Bad!Bad!Bad!



>>> X = 1; Y = 2
>>> print(X, Y)                                            # Print: the easy way
1 2
>>> import sys                                             # Print: the hard way
>>> sys.stdout.write(str(X) + ' ' + str(Y) + '\n')
1 2
4
>>> print(X, Y, file=open('temp1', 'w'))                   # Redirect text to file

>>> open('temp2', 'w').write(str(X) + ' ' + str(Y) + '\n') # Send to file manually
4
>>> print(open('temp1', 'rb').read())                      # Binary mode for bytes
b'1 2\r\n'
>>> print(open('temp2', 'rb').read())
b'1 2\r\n'


#python26使用python3中的print函数
from __future__ import print_function

#python3.0的形式
C:\misc> c:\python30\python
>>> print('spam')                       # 3.0 print function call syntax
spam
>>> print('spam', 'ham', 'eggs')        # These are mutiple argments
spam ham eggs

#打印多个对象python2.6会多出括号,变成元组
C:\misc> c:\python26\python
>>> print('spam')                       # 2.6 print statement, enclosing parens
spam
>>> print('spam', 'ham', 'eggs')          # This is really a tuple object!
('spam', 'ham', 'eggs')


>>> print('%s %s %s' % ('spam', 'ham', 'eggs'))
spam ham eggs
>>> print('{0} {1} {2}'.format('spam', 'ham', 'eggs'))
spam ham eggs


#定义提供write方法的类
class FileFaker:
    def write(self, string):
        # Do something with printed text in string

import sys
sys.stdout = FileFaker()
print(someObjects)              # Sends to class write method

myobj = FileFaker()             # 3.0: Redirect to object for one print
print(someObjects, file=myobj)  # Does not reset sys.stdout

myobj = FileFaker()             # 2.6: same effect
print >> myobj, someObjects     # Does not reset sys.stdout

python script.py < inputfile > outputfile
python script.py | filterProgram


要把一个单个的打印操作打印到一个文件,可以使用python3的print(X, file=F)的调用形式,
或者使用python26的扩展的print >> file, X语句形式,
或者在打印前把sys.stdout 指定为手动打开的文件并在之后恢复最初的值。
你也可以使用系统shell的特殊语法,把程序所有的打印文字重定向到一个文件。












评论

此博客中的热门博文

OAuth 2教程

网格策略

apt-get详细使用