1. 程式人生 > >Python變數和物件型別速記手冊

Python變數和物件型別速記手冊

變數和物件型別

Python中關於變數和物件型別有一些重要的概念:

變數不受型別約束

變數並不是一塊記憶體空間的標籤,只是物件的名字,是沒有型別的,相當於一個可以指向任何物件void指標。型別屬於物件,而不是變數。

動態型別 它自動地跟蹤你的型別而不是要求宣告程式碼;Python中沒有型別宣告,執行的表示式,決定了建立和使用的物件的型別
強型別 型別是不可變的,一旦發生強制型別轉換,則意味著新的物件的建立。你只能對一個物件進行有效的操作。
多型 由於型別不受約束,Python編寫的操作通常可以自動地適用於不同型別的物件,只要他們支援一種相容的介面(類似C++裡模板的概念),就像‘+’操作對於數字為加法,對於序列為合併。
物件頭部資訊 物件的記憶體空間,除了值外,還有
1 一個型別識別符號(標識物件型別)
2 一個應用計數器(用來決定是不是可以回收這個物件)sys.getrefcount(1)
物件型別檢測 在Python中,我們編寫物件介面而不是型別。不關注與特定型別意味著程式碼會自動地適應於他們中的很多型別:任何具有相容介面的物件均能工作。

1. type(L) == type([])

2. type(L) == list

3. isinstance(L,list)

儘管支援型別檢測,但這並不是一個“Python式”的思維方式,破壞了程式碼的靈活性。

賦值

基本賦值、元組賦值、列表賦值和多目標賦值。在賦值語句中,即使沒有圓括號,也能識別出來這是一個元組。

image序列賦值語句:支援右側任何可迭代物件(左右元素數目相同)

[a,b,c] = (1,2,3)或 [a,b,c] = '123'或 red,green,blue = range(3)

image

交換值不需要中間變數

image

需要注意引用的陷阱:

image

對於支援原地修改的物件而言,增強賦值語句會執行原地修改運算L.append(4) L.extend([7,8]),比合並(複製過程)L = L + [4] 執行得更快.

image

隱式賦值語句:模組匯入import,from;函式和類的定義def,class;for迴圈變數;函式引數

在函式中接收元組和列表

當要使函式接收元組或字典形式的引數的時候,有一種特殊的方法,它分別使用*和**字首。這種方法在函式需要獲取可變數量的引數的時候特別有用。

image
>>> def powersum(power, *args):
...     '''Return the sum of each argument raised to specified power.'''
...     total = 0
...     for i in args:
...          total += pow(i, power)
...     return total
...
>>> powersum(2, 3, 4)
25

>>> powersum(2, 10)
100

引用傳遞

在 Python 中所有賦值操作都是“引用傳遞”。當把一個物件賦給一個數據結構元素或者變數名時,Python總是會儲存物件的引用,而不是物件的一個拷貝(除非明確要求拷貝)。

通過將一些基本資料型別(數值、字串、元組)設為不可改變物件,可以模擬“值傳遞”,例如:

userName = ‘tonyseek’   #字串物件為不可變物件,保護完整性
otherUserName = userName  #指向新建立的另一個字串物件

otherUserName = ‘It’s not tonyseek’  #改變的不是userName指向的內容

儲存物件引用

列表和元組都被認為是“物件引用”的陣列(在標準Python直譯器內部,就是C陣列而不是連結結構,索引速度較快)。

淺拷貝和深拷貝

淺拷貝只拷貝頂層結構,深拷貝是遞迴的拷貝。

如果你想要複製一個列表或者類似的序列或者其他複雜的物件(不是如整數那樣的簡單物件 ),那麼你可以使用切片操作符來取得拷貝。如果你只是想要使用另一個變數名,兩個名稱都 參考 同一個物件,那麼如果你不小心的話,可能會引來各種麻煩。

X = [1,2,3]

L1 = [X,X,X]

L2 = [X[:],list(X),copy.copy()] #頂層複製

L.append(L) #無限迴圈物件,複合物件包含指向自身的引用·

不變物件的快取和複用 作為一種優化,Python快取了不變的物件並對其進行復用,例如小的整數和字串。因為不能改變數字和字串,所以無論對同一個物件有多少個引用都沒有關係,從邏輯的角度看,這工作起來就像每一個表示式結果的值都是一個不同的物件,而每一個物件都是不同的記憶體。
垃圾收集

當最後一次引用物件後(例如,將這個變數用其他的值進行賦值),這個物件所有佔用的記憶體空間將會自動清理掉

Python中有幾種主要的核心資料型別:

1 數值【不可變】

負數 -x
正數 +x
按位翻轉 ~x=-(x+1)

絕對值

abs(x)

若x位複數,返回複數模

用x除以y,返回包含商和餘數的tuple值(int(x/y),x%y) divmod(x, y)

x的y次幕(x ** y ) x % modulo

pow(x ,y [,modulo])

返回值型別與x同

複數 complex (x[,y])

將x做實部,y做虛部建立複數

整數 int(x)

將字串和數字轉換為整數,對浮點進行舍位而非舍入

long(x)

將字串和數字轉換為長整形

浮點數 float(x)

將str和num轉換為浮點物件

四捨五入,n為小數點位數 round(x[,n])
進位制轉換

hex(x) 將整數或長整數轉換為十六進位制字串

oct(x) 將整數或長整數轉換為八進位制字串

平方根 math.sqrt(math.pi*85)
>= x 的最小整數 math.ceil(x)
<= x的最大整數 math.floor(x)
對 x 朝向 0 取整 math.trunc(x)
隨機:數字生成

>>> random.random()   #浮點數,x in the interval [0, 1)
0.8759095262051569

>>> random.getrandbits(16) #a python long int with k random bits

9213L

>>> random.uniform(1,1000) #浮點數in the range [a, b) or [a, b]

400.88489201157114

>>> random.randint(1,1000) #整數random integer in range [a, b] 不推薦使用

817

>>> random.randrange(0,1001,2) #整數from range([start,] stop[, step]) 推薦使用

822

隨機:序列操作sequences
---------
pick random element
random sampling without replacement

generate random permutation

>>> random.choice([0,1,2,3]) #a random element
2

>>> random.sample(xrange(10000000), 3) #unique random elements
[9435040, 5756107, 8741537]

>>> random.shuffle(list)  #洗牌,就地shuffle list,無返回值.可選引數random是一個返回[0.0, 1.0)間浮點數的無參函式名,預設為random.random.

On the real line, there are functions to compute uniform, normal (Gaussian), lognormal, negative exponential, gamma, and beta distributions. For generating distributions of angles, the von Mises distribution is available.
  • 整型int
  • 長整型long(無限精度)
  • 浮點數float(雙精度)
  • 十進位制數/小數decimal(固定精度浮點數)
  • 複數complex
  • 分數fraction

2 序列【有序】【索引:偏移量】 

序列通用型操作 內建函式或表示式
合併 ‘+’
不允許+表示式中混合數字和字串,使用'123'+str(9)或者int('123')+9
重複 ‘*’
>>> print '----------------------------------------'
>>> print '-'*40
索引(dictionary使用鍵) seq[i]=seq[len(seq)-i],i是偏移量
切片 seq[i:j:d](步長d=-1表示分片將會從右至左進行,實際效果就是反轉序列)
將列表片段重新賦值 s[i :j ] = r 
刪除列表中一個片段 del s[i :j ]
image
求長度(dictionary,set支援) len(seq)
單個最大/最小值 max(seq),min(seq)
每項最大/最小值組成的序列 max(seq[,…]),min(seq[,…])
迭代協議 列表解析,in成員關係測試,map內建函式以及sorted,sum,any,all呼叫等其他內建函式
sum,any,all sum返回可迭代物件中所有數字的和,可迭代物件中的任何/全部元素為True,any/all內建函式返回True
排序(dictionary返回鍵的列表,set支援,tuple不支援) sorted(seq)
t = tuple(sorted(list(t))) 
操作sorted(seq)返回物件;方法seq.sort()(tuple不支援)排序後不返回物件
從屬關係(dictionary,set支援) x in seq, x not in seq
迭代 遍歷訪問元素:for x in seq:
遍歷訪問元素和索引:for index, item in enumerate(sequence): 
使用range來產生索引:range(2,9,2)

>>> range(0,10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(9,-1,-1)
[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

同時遍歷多個序列:zip(L1,L2)/map(None,L1,L2)

zip函式轉置二維列表:

>>> l = [[1, 2, 3], [4, 5, 6]]
>>> zip(*l)
[(1, 4), (2, 5), (3, 6)]
列表解析(dictionary,set支援)

列表解析替代巢狀迴圈:for迴圈和列表解析(通常比對應的for迴圈執行得更快)都是通用迭代工具,都能工作於遵守迭代協議的任意物件(可遍歷物件,包括可自逐行讀取的檔案)

>>> M = [[1,2,3],[4,5,6],[7,8,9]]
>>> column = [row[1] for row in M if row[1]%2 == 0]
>>> column
[2, 8]
>>> diag = [M[i][i] for i in [0,1,2]]
>>> diag
[1, 5, 9]

>>> squares = [x**2 for x in [1,2,3,4,5]]

>>> squares

[1, 4, 9, 16, 25]

列表解析也可用於元組的轉換:

>>> T = (1,2,3,4,5)

>>> L = [x+20 for x in T]

>>> L

[21, 22, 23, 24, 25]

>>> [line.upper() for line in open('script1.py')]

map呼叫 >>> map(str.upper,open('script1.py')) #對可迭代物件每個元素都應用一個函式呼叫

2.1 字串string【同構】【不可變】

字元的有序集合(雖然元素間沒有分隔符)

>>> set('abcde')
set(['a', 'c', 'b', 'e', 'd'])

‘\0’不會中斷字串

>>> s = "a\0b\tc\c" 
>>> s
'a\x00b\tc\\c'
>>> len(s)
7

raw字串 r’\temp\spam’
型別方法 find(s),isdigit(),isalpha()
upper(),lower(),replace(s0,s1),split(‘’),rstrip()
不可變:模擬改變元組

1 合併、分片、索引 
where = S.find('SPAM')
S = S[:where] + 'EGGS' +S[(where+4):]
2 字串方法 
S = S.replace('pl','pamal') #replace all
S = S.replace('pl','pamal',1) #replace once
role,words = line.split(':',1) #split([sep[,maxsplit]]) ->list of strings

3 轉化為可變物件
L = list(S)
L[3] = 'x'
S = ''.jion(L)
line = 'bob,hacker,40\n'
line.rstrip()
line.split(',')
[bob,hacker,40]

字串格式化 s % type
%[(name)][flags][width][.precision]code
%[(鍵)][左對齊(-)正負號(+)補零(0)][整體寬度][.小數位數]code
基於元組的格式化:'%s is %d years old' % (name, age)
基於字典的格式化:'%s(age)d %(food)s' % vars()
%s 任何物件的字串表達(使用str)
%r 任何物件的字串表達(使用repr)
%% 常量%
正則表示式(使用模式定義字串)
實現更多搜尋,分割,替換

>>> import re
>>> match = re.match('[/]usr/(.*)/(.*)','/usr/home/jack')
>>> type(match)
<type '_sre.SRE_Match'>
>>> match.groups()
('home', 'jack')

物件的字串表達 str(o):string used by print(user-friendly) 列印(使用者友好)
repr(o):as-code string used by echoes 互動式回顯

2.2 unicode字串 【同構】【不可變】 u’spam’

支援所有的字串操作

2.3 元組tuple【異構】【不可變】    t = (1,2,’3’)

不可變

元組的不可變性只適用於元組本身的頂層結構而並非其內容:

>>>T = (1,[2,3],4)

>>> T[1] = 'spam'
TypeError: 'tuple' object does not support item assignment

>>> T[1][0] = ‘spam’

>>> T

(1, ['spam', 3], 4)

類似“常數”宣告:提供完整性約束 如果在程式中以元組的形式傳遞一個物件的集合,可以確保元組在程式中不會被另一個引用修改,而列表就沒有這樣的保證了。(利於編寫大型程式)
與其他語言中的const概念不同,在Python中其是與物件相結合的(元組物件本身的不可變性),而不是變數。

2.4 列表list【異構】【可變】          l = [1,2,’3’]

可變 禁止獲取一個不存在的元素
禁止邊界外的賦值
陷阱:遍歷並修改列表 簡單的for迴圈並不能修改列表,和C++中的迭代器用法不一樣
C++(for語句+迭代器)遍歷並修改列表(輸出222)
vector<int> vint;
vector<int>::iterator i;
vint.resize(3,1);
for(i = vint.begin(); i != vint.end();++i)    *i += 1;
for(i = vint.begin(); i != vint.end();++i)    cout << *i;
Python的for語句(這種foreach概念在C++中是沒有的)不行:
image
型別方法 count(x),index(x)
append(x),insert(i,x),extend(list)
pop(i),remove(x),del L[i],del L[i:j]
sort(),reverse()
index(x)和remove(x)對匹配物件x的第一個元素進行操作,無匹配時異常

3 對映【無序】【索引:鍵】

3.1 字典dictionary【異構】【可變】 d = {1:’I’,2:’Love’,’3’:'Python’}

可變 對新的字典的鍵賦值,會建立該鍵 x[key] = value
可以刪除一個鍵值對 
禁止獲取一個不存在的鍵值 x[key]

Python的dict實現,其實就是一個hash map,因此要求Key是hashable的

鍵為不可變物件:數字和字串,只包括(像數字和字串這樣的)不可變引數的元組,才可以作為字典中有效的鍵。大多數Python物件可以作為鍵;但它們必須是可雜湊的物件。

像列表和字典這樣的可變型別,由於它們不是可雜湊的,所以不能作為鍵。 也有一些可變物件(很少)是可雜湊的。

唯一 一鍵對應多個值是不允許的
獲取元素列表 keys()返回鍵的列表,values()返回值的列表,items()返回tuples的列表
獲取元素迭代器 iteritems(), iterkeys(), 和itervalues()這些函式與返回列表的對應方法相似,只是它們返回惰性賦值的迭代器,所以節省記憶體。
for k in d: 等價於 for k in d.keys():
'+'有序合併操作失效

update(x2) 用字典x2中的鍵/值對新增到原字典。重複鍵所對應的原有條目的值將被新鍵所對應的值所覆蓋。

其他型別方法

get(x[,y]) 返回鍵x對應的值。若未找到返回default的值(注意,引數default的預設值為None)。get()方法和鍵查詢(key-lookup)操作符( [ ] )相似,不同的是它允許你為不存在的鍵提供預設值。如果該鍵不存在,也未給出它的預設值,則返回None。此方法比採用鍵查詢(key-lookup)更靈活,因為你不必擔心因鍵不存在而引發異常。

pop(key) ,del d[key]

clear() 刪除詞典的所有條目。

構造

D0 = {'name' = 'Bob', 'age' = 42}

D1 = dict(name = 'Bob', age = 42)

D2 = dict.fromkeys(seq, val=None) 建立並返回一個新字典,以seq中的元素做該字典的鍵,val做該字典中所有鍵對應的初始值(如果不提供此值,則預設為None)

D3 = dict(zip(keylist,vallist))

拷貝

copy() 淺拷貝:返回字典的高層結構的拷貝,但不復制嵌入結構,而複製那些結構的引用。

copy模組:copy.copy(x) copy.deepcopy(x)

避免獲取不存在的字典鍵錯誤 if d.has_keys(k)(最好使用if k in d)測試
get方法為不存在的鍵提供預設值 d.get(key,defaultval)
D. get ( "Newton" , "unknown" ) # = ' unknown '
try:XXX except KeyError:XXX 語句捕獲修復異常等

4 擴充套件

4.1 集合set【無序】【異構】【可變】s = set([1,2,’3’]) <=set(t|l|d)

差集 ‘-’
並集 ‘|’
交集 ‘&’

4.2 檔案file f = open(‘examples/data.txt’,’w’)

open引數 open(name[, mode[, buffering]]) -> file object
檔名:
在Python中,斜槓’/’永遠都是正確的,即使是在Windows環境下。所有現代的作業系統(甚至Windows!)使用Unicode編碼方式來儲存檔名和目錄名。
處理模式字串:

'r', 'w' or 'a' for reading (default),writing or appending. 寫或追加模式下若檔案不存在則建立它。

字串尾部加’b’可以進行二進位制資料處理(行末轉換關閉);加‘+’同時為輸入輸出開啟;加‘U’實現input file的universal newline support(不能與'w' or '+'同時使用) 
buffering引數:

控制輸出快取,0 代表無快取(寫入方法呼叫時立即傳給外部檔案)0 means unbuffered, 1 means line buffered, and larger numbers specify the buffer size.

檔案迭代器 從文字檔案中讀取文字行的最佳方式是根本不用讀取檔案:使用迭代器逐行讀取(讓for迴圈在每輪自動呼叫next從而前進到下一行)
for line in open('test.txt'):print line
常用檔案讀操作
aString = input.read()
aString = input.read(N)
aString = input.readline()
讀取[整個檔案]到一個字串
讀取[之後N個位元組]到一個字串
讀取[下一行(包括行末標誌符)]到一個字串
aList = input .readlines()
aList = input.xreadlines()
讀取[整個檔案]到{字串列表}

返回空字串:檔案底部; 返回包含新行符的字串:空行
for line in open('test.txt').readlines():print line #比檔案迭代器麻煩
while ... :   #效率比for差
   line  = file.readline()
   if not line:break 

常用檔案寫操作
output.write(aString) 寫入{位元組字串}到檔案,並不會新增行終止符
output.writelines(aList) 寫入{列表內所有字串}到檔案

寫入方法不新增行終止符

重定向輸出流

import sys
sys.stdout = open('log.txt', 'a') # Redirects prints to a file
...
print(x, y, x) # Shows up in log.txt

暫時重定向

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

print >> sys.stderr, 'Bad'*8

output.close() 手動關閉(當檔案收集完成時會替你關閉檔案)
output.flush() 把輸出緩衝區刷到硬碟上,但不關閉檔案
anyFile.seek(N) 修改檔案位置到偏移量N處(以便進行下一個操作)
位元組字串 從檔案讀取的資料回到指令碼時是一個字串
寫檔案時使用轉換工具把物件轉化為字串(print不用)
1 eval能夠吧字串當做可執行程式碼
>>>eval['[1,2,3]']
[1,2,3]
2 pickle模組處理一般物件的儲存
>>>import pickle
>>>pickle.dump(D,ofie)
>>>ofile.close()
>>>E = pickle.load(ifile) 
3 struct模組處理檔案中的二進位制資料

4.3 位元組Byte

4.4 布林型bool

0,'',(),[],{},None

false

'string',>1,<-1

true

4.5 其他

記住,尋求幫助最好的辦法是dir(object)和help(object.method)。

5.補充介紹

集合set,十進位制數decimal,布林值bool,佔位符None

5.1集合set

set(集合)是非常有用的資料型別,可以用來處理集合型別的資料。最開始在Python 2.3引入,從Python 2.4開始變為內建型別(不需匯入模組)。

什麼是集合?無序、唯一。如果你想要檢測一個值是否在集合中,sets在這一點非常的高效,比list快多了。

和之前所見的資料型別不一樣(和file一樣),沒有特定的常量語法建立set物件,需要使用set的建構函式,生成一個set可以從序列(string、list、tuple)甚至對映(dictionary)直接生成。

set支援一般的數學集合操作,處理較大的資料集合時是很方便的。

>>>X = set("spam")    #make 2 sets out of sequences
>>>Y = set(['h','a'])
>>>Y.add('m')         #元素唯一性
>>>Y.add('m')
>>>X,Y
(set(['a','p','s','m']),set(['h','a','m']))
>>>X & Y              #Intersection 並集
set(['a','m'])
>>>X | Y              #Union 交集
set(['a','p','s','h','m'])
>>>X - Y              #Difference 差集
set(['p','s'])

如果直接使用dictionary構造,則會取出鍵值作為集合的元素,如果想將字典的值生成集合怎麼辦呢?

>>> a = {3:'c',2:'b',1:'a'}
>>> print a
{1: 'a', 2: 'b', 3: 'c'}
>>> print sorted(a)
[1, 2, 3]
>>> b = set(a)
>>> print b
set([1, 2, 3])
>>> print sorted(b)
[1, 2, 3]
>>> c = set(a.values())
>>> print c
set(['a', 'c', 'b'])
>>> print sorted(c)
['a', 'b', 'c']

5.2 布林型bool

Python2.3引入了明確的布林資料型別bool,其值為True和False,而且True和False是預先定義的內建變數名。在內部,內建變數名True和False是bool的例項,實際上僅僅是內建的int的子類。

True和False的行為和整數1和0是一樣的,除了他們有特定的邏輯列印形式(bool重新定義了str和repr的字串格式),也就是說,True僅僅是定製了顯示格式的整數1,在Python中True+3=4!

5.3 佔位符None

Python長期以為一直支援特殊的佔位符物件None:

>>> X = None       #None placeholder
>>> X
>>> print X
None
>>> L = [None]*10
>>> L
[None, None, None, None, None, None, None, None, None, None]
>>> type(L)        #Types
<type 'list'>
>>> type(type(L))  #Even types are objects
<type 'type'>

5.4 十進位制數decimal(固定精度浮點數)

首先需要

>>> import decimal

和普通浮點數的區別:

>>> d = 3.141
>>> d + 1
4.141
>>> d + 1.111111
4.252111
>>> d + 1.1111111
4.2521111000000005
>>> d = decimal.Decimal('3.141')
>>> d + 1
Decimal('4.141')
>>> d + 1.111111
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'Decimal' and 'float'
>>> d + decimal.Decimal('1.1111111')
Decimal('4.2521111')

更多資料結構,請查閱官方文件

其他的Python要點

效能優化 Python中一個主要的原則是:首先為了簡單和可讀性去編寫程式碼,在程式執行後,並證明了確實有必要考慮效能後,再考慮該問題(time,timeit,profile模組)。更多情況是程式碼本身就已經足夠快了。

面向物件

基本概念一樣,this由代替self, 而且這個名字不一定要寫成self,任何名字都可以,這也帶來了一個缺點,你必須在形參裡面指定,呼叫函式時不用傳遞該引數。
建構函式:__init__(self, ......)
解構函式:__del__ 物件滅亡時或者呼叫del時被呼叫
Python中所有的類成員(包括資料成員)都是公共的 ,所有的方法都是有效的 。只有一個例外:如果你使用的資料成員名稱以 雙下劃線字首 比如__privatevar,Python的名稱管理體系會有效地把它作為私有變數。

儲存器

cPickle和pickle是叫做儲存器的重要模組,可以非常方便地將一個物件儲存到一個檔案,然後再取儲存從檔案中取出來pickle.dump(object, file object),構造物件時,pickle.load(file object) [儲存、取儲存]

異常

raise,except,try...finally

系統庫 sys模組和os模組有很多強大功能,比如說os.system(命令)可用於執行shell命令
lambda形式

lambda語句被用來建立新的函式物件,並且在執行時返回它們。lambda語句用>來建立函式物件。本質上,lambda需要一個引數,後面僅跟單個表示式作為函式體,而表示式的值被這個新建的函式返回。

注意,即便是print語句也不能用在lambda形式中,只能使用表示式。

image

image

image

Python語句

image

image

image

random模組高階用法:

distributions on the real line:
------------------------       uniform
       triangular
       normal (Gaussian)
       lognormal
       negative exponential
       gamma
       beta
       pareto
       Weibull
distributions on the circle (angles 0 to 2pi)
------------------------       circular uniform
       von Mises

uniform(self, a, b)

|      Get a random number in the range [a, b) or [a, b].

triangular(self, low=0.0, high=1.0, mode=None)
|      Triangular distribution.

gauss(self, mu, sigma)
|      Gaussian distribution.

normalvariate(self, mu, sigma)
|      Normal distribution.

lognormvariate(self, mu, sigma)
|      Log normal distribution.

expovariate(self, lambd)
|      Exponential distribution.

gammavariate(self, alpha, beta)
|      Gamma distribution.  Not the gamma function!

betavariate(self, alpha, beta)
|      Beta distribution.

paretovariate(self, alpha)
|      Pareto distribution. 

weibullvariate(self, alpha, beta)
|      Weibull distribution.

vonmisesvariate(self, mu, kappa)
|      Circular data distribution.

internal state

seed(self, a=None)
|      Initialize internal state from hashable object.

setstate(self, state)
|      Restore internal state from object returned by getstate().

getstate(self)
|      Return internal state; can be passed to setstate() later.

jumpahead(self, n)
|      Change the internal state to one that is likely far away
|      from the current state.  This method will not be in Py3.x,
|      so it is better to simply reseed.