并发编程

创建线程


In [ ]:
import threading
import time
 
def counter(n):  
    cnt = 0;  
    for i in xrange(n):  
        cnt += 1
        time.sleep(0.1)
        print cnt             
               
th = threading.Thread(target=counter, args=(10,));   
th.start();  
th.join(); 
print 'main thread task done'

创建线程-继承类


In [ ]:
import threading, time, random  
  
def counter():  
    cnt = 0;  
    for i in xrange(10000):  
        for j in xrange(i):  
            cnt += j;  
  
class SubThread(threading.Thread):  
    def __init__(self, name):  
        threading.Thread.__init__(self, name=name);  
        pass
  
    def run(self):  
        i = 0;  
        while i < 3:  
            print self.name,'counting...\n';  
            counter();  
            print self.name,'finish\n';  
            i += 1;  

th = SubThread('thread-1');  
th.start();  
th.join();  
print 'all done';

In [ ]:
import threading, time
  
class SubThread(threading.Thread):  
    def __init__(self, name):  
        threading.Thread.__init__(self, name=name);  
  
    def run(self):  
        i = 0;  
        while i < 3:  
            print self.name,'counting...\n';  
            time.sleep(1) 
            print self.name,'finish\n';  
            i += 1;  

th = SubThread('thread-1');
print 'main start'
th.setDaemon(False)
th.start()  
th.join() 
print 'main end'

Daemon守护线程

外部运行

线程同步


In [ ]:
from threading import Thread
some_var = 0
class IncrementThread(Thread):
    def run(self):
        global some_var
        read_value = some_var
        print "some_var in %s is %d" % (self.name, read_value)
        some_var = read_value + 1
        #print "some_var in %s after increment is %d" % (self.name, some_var)
def use_increment_thread():
    threads = []
    for i in range(50):
        t = IncrementThread()
        threads.append(t)
        t.start()
    for t in threads:
        t.join()
    print "After 50 modifications, some_var should have become 50"
    print "After 50 modifications, some_var is %d" % (some_var,)
use_increment_thread()

In [ ]:
# lock
# 可以通过下面两种方式创建一个Lock对象,新创建的 Lock 对象处于未上锁的状态:
import threading
l = threading.Lock()
l

In [ ]:
from threading import Lock, Thread
lock = Lock()
some_var = 0
class IncrementThread(Thread):
    def run(self):
        #we want to read a global variable
        #and then increment it
        global some_var
        lock.acquire()
        read_value = some_var
        print "some_var in %s is %d" % (self.name, read_value)
        some_var = read_value + 1
        print "some_var in %s after increment is %d" % (self.name, some_var)
        lock.release()
def use_increment_thread():
    threads = []
    for i in range(50):
        t = IncrementThread()
        threads.append(t)
        t.start()
    for t in threads:
        t.join()
    print "After 50 modifications, some_var should have become 50"
    print "After 50 modifications, some_var is %d" % (some_var,)
use_increment_thread()

In [ ]:
# 不加锁计数器
import time
from threading import Thread
value = 0
def getlock():
    global value
    new = value + 1
    time.sleep(0.001)  # 使用sleep让线程有机会切换
    value = new
threads = []
for i in range(100):
    t = Thread(target=getlock)
    t.start()
    threads.append(t)
for t in threads:
    t.join()
print value

In [ ]:
# 加锁保证结果
import time
from threading import Thread, Lock
value = 0
lock = Lock()
def getlock():
    global value
    with lock:
        new = value + 1
        time.sleep(0.001)
        value = new
threads = []
for i in range(100):
    t = Thread(target=getlock)
    t.start()
    threads.append(t)
for t in threads:
    t.join()
print value

In [ ]:
import threading  
import time  
  
def test_xc(): 
    mutex.acquire()#取得锁  
    f = open("test.txt","a")  
    f.write("test_dxc"+'\n')  
    f.close()  
    mutex.release()#释放锁  
 
mutex = threading.Lock()#创建锁 
threads = []
for i in xrange(5):  
    t = threading.Thread(target=test_xc)  
    t.start()  
    threads.append(t)
for t in threads:
    t.join()

可重入锁


In [ ]:
import threading

print 'lock acquire'
lock = threading.Lock()
lock.acquire()
lock.acquire()
lock.release()
lock.release()
print 'done'

In [ ]:
import threading

print 'lock acquire'
lock = threading.RLock()
lock.acquire()
lock.acquire()
lock.release()
lock.release()
print 'done'

Condition


In [ ]:
import threading, time
class Hider(threading.Thread):
    def __init__(self, cond, name):
        super(Hider, self).__init__()
        self.cond = cond
        self.name = name
    def run(self):
        time.sleep(1) #确保先运行Seeker中的方法
        self.cond.acquire() #b
        print self.name + ': 我已经把眼睛蒙上了'
        self.cond.notify()
        self.cond.wait() #c
                         #f
        print self.name + ': 我找到你了 ~_~'
        self.cond.notify()
        self.cond.release()
                            #g
        print self.name + ': 我赢了'   #h
class Seeker(threading.Thread):
    def __init__(self, cond, name):
        super(Seeker, self).__init__()
        self.cond = cond
        self.name = name
    def run(self):
        self.cond.acquire()
        self.cond.wait()    #a    #释放对琐的占用,同时线程挂起在这里,直到被notify并重新占有琐。
                            #d
        print self.name + ': 我已经藏好了,你快来找我吧'
        self.cond.notify()
        self.cond.wait()    #e
                            #h
        self.cond.release()
        print self.name + ': 被你找到了,哎~~~'
cond = threading.Condition()
seeker = Seeker(cond, 'seeker')
hider = Hider(cond, 'hider')
seeker.start()
hider.start()

Event 交通灯


In [ ]:
import threading
import random
import time


class VehicleThread(threading.Thread):
    """Class representing a motor vehicle at an intersection"""

    def __init__(self, threadName, event):
        """Initializes thread"""

        threading.Thread.__init__(self, name=threadName)

        # ensures that each vehicle waits for a green light
        self.threadEvent = event

    def run(self):
        """Vehicle waits unless/until light is green"""

        # stagger arrival times
        time.sleep(random.randrange(1, 10))

        # prints arrival time of car at intersection
        print "%s arrived at %s\n" % \
              (self.getName(), time.ctime(time.time()))

        # wait for green light
        self.threadEvent.wait()

        # displays time that car departs intersection
        print "%s passes through intersection at %s\n" % \
              (self.getName(), time.ctime(time.time()))


greenLight = threading.Event()
vehicleThreads = []

# creates and starts five Vehicle threads
for i in range(1, 5):
    vehicleThreads.append(VehicleThread("Vehicle" + str(i),
                                        greenLight))

for vehicle in vehicleThreads:
    vehicle.start()

while threading.activeCount() > 1:
    # sets the Event's flag to false -- block all incoming vehicles
    greenLight.clear()
    print "RED LIGHT! at", time.ctime(time.time())
    time.sleep(3)

    # sets the Event's flag to true -- awaken all waiting vehicles
    print "GREEN LIGHT! at", time.ctime(time.time())
    greenLight.set()
    time.sleep(1)

信号量


In [1]:
import time
from random import random
from threading import Thread, Semaphore
sema = Semaphore(3)
def foo(tid):
    with sema:
        print '{} acquire sema'.format(tid)
        wt = random() * 2
        time.sleep(wt)
    print '{} release sema'.format(tid)
threads = []
for i in range(5):
    t = Thread(target=foo, args=(i,))
    threads.append(t)
    t.start()
for t in threads:
    t.join()


0 acquire sema1 acquire sema 2 acquire sema


2 release sema3 acquire sema

4 acquire sema
0 release sema
3 release sema
4 release sema
1 release sema

进程


In [2]:
import multiprocessing

def foo(i):
   print 'called function in process: %s' % i
   return
    
Process_jobs = []
for i in range(5):
   p = multiprocessing.Process(target=foo, args=(i,))
   Process_jobs.append(p)
   p.start()
   p.join()


called function in process: 0
called function in process: 1
called function in process: 2
called function in process: 3
called function in process: 4

后台进程


In [3]:
import multiprocessing
import time

def foo():
   name = multiprocessing.current_process().name
   print ("Starting %s \n" %name)
   time.sleep(3)
   print ("Exiting %s \n" %name)

background_process = multiprocessing.Process\
                    (name='background_process',\
                     target=foo)
background_process.daemon = True
NO_background_process = multiprocessing.Process\
                          (name='NO_background_process',\
                           target=foo)
NO_background_process.daemon = False
background_process.start()
NO_background_process.start()


Starting background_process 

Starting NO_background_process 

Exiting background_process 

Exiting NO_background_process 

杀死进程


In [4]:
import multiprocessing
import time
def foo():
    print ('Starting function')
    time.sleep(0.1)
    print ('Finished function')

p = multiprocessing.Process(target=foo, name='Process-#Test#')
print ('Process before execution:', p, p.is_alive())
p.start()
print ('Process running:', p, p.is_alive())
p.terminate()
print ('Process terminated:', p, p.is_alive())
p.join()
print ('Process joined:', p, p.is_alive())
print ('Process exit code:', p.exitcode)


('Process before execution:', <Process(Process-#Test#, initial)>, False)
('Process running:', <Process(Process-#Test#, started)>, True)
('Process terminated:', <Process(Process-#Test#, started)>, True)
('Process joined:', <Process(Process-#Test#, stopped[SIGTERM])>, False)
('Process exit code:', -15)

继承创建进程


In [5]:
import multiprocessing
class MyProcess(multiprocessing.Process):
  def run(self):
     print ('called run method in process: %s' %self.name)
     return


jobs = []
for i in range(5):
    p = MyProcess ()
    jobs.append(p)
    p.start()
    p.join()


called run method in process: MyProcess-9
called run method in process: MyProcess-10
called run method in process: MyProcess-11
called run method in process: MyProcess-12
called run method in process: MyProcess-13

进程间通信

进程共享内存


In [6]:
from multiprocessing import Process, Value, Array

def f(n, a):
    n.value = 3.1415927
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == '__main__':
    num = Value('d', 0.0)
    arr = Array('i', range(10))

    p = Process(target=f, args=(num, arr))
    p.start()
    p.join()

    print num.value
    print arr[:]


3.1415927
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]

进程共享-队列


In [7]:
import multiprocessing
import random
import time
class producer(multiprocessing.Process):
    def __init__(self, queue):
        multiprocessing.Process.__init__(self)
        self.queue = queue
    def run(self) :
        for i in range(10):
            item = random.randint(0, 256)
            self.queue.put(item)
            print ("Process Producer : item %d appended to queue %s" % (item,self.name))
            time.sleep(1)
            print ("The size of queue is %s" % self.queue.qsize())
class consumer(multiprocessing.Process):
    def __init__(self, queue):
        multiprocessing.Process.__init__(self)
        self.queue = queue
    def run(self):
        while True:
            if (self.queue.empty()):
                print("the queue is empty")
                break
            else :
                time.sleep(2)
                item = self.queue.get()
                print ('Process Consumer : item %d popped from by %s \n' % (item, self.name))
        time.sleep(1)

In [8]:
queue = multiprocessing.Queue()
process_producer = producer(queue)
process_consumer = consumer(queue)
process_producer.start()
process_consumer.start()
process_producer.join()
process_consumer.join()

# 如果多个consumer,进程同步


Process Producer : item 15 appended to queue producer-15
Process producer-15:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "<ipython-input-7-ec6a1a3b1a52>", line 14, in run
    print ("The size of queue is %s" % self.queue.qsize())
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/queues.py", line 143, in qsize
    return self._maxsize - self._sem._semlock._get_value()
NotImplementedError
Process Consumer : item 15 popped from by consumer-16 

the queue is empty

管道


In [9]:
from multiprocessing import Process, Pipe
 
 
class Consumer(Process):
    def __init__(self, pipe):
        Process.__init__(self)
        self.pipe = pipe
 
    def run(self):
        self.pipe.send("Consumer Words")
        print "Consumer Received:", self.pipe.recv()
 
 
class Producer(Process):
    def __init__(self, pipe):
        Process.__init__(self)
        self.pipe = pipe
 
    def run(self):
        print "Producer Received:", self.pipe.recv()
        self.pipe.send("Producer Words")
 
 
pipe = Pipe()
p = Producer(pipe[0])
c = Consumer(pipe[1])
p.daemon = c.daemon = True
p.start()
c.start()
p.join()
c.join()
print "Ended!"


Producer Received: Consumer Words
Consumer Received: Producer Words
Ended!

进程池


In [10]:
#阻塞方式
from multiprocessing import Lock, Pool
import time
 
 
def function(index):
    print "Start process: ", index
    time.sleep(3)
    print "End process", index
 
 
pool = Pool(processes=3)
for i in xrange(4):
    pool.apply(function, (i,))

print "Started processes"
pool.close()
pool.join()
print "Subprocess done."


Start process:  0
End process 0
Start process:  1
End process 1
Start process:  2
End process 2
Start process:  3
End process 3
Started processes
Subprocess done.

In [11]:
# 非阻塞方式
from multiprocessing import Lock, Pool
import time
 
 
def function(index):
    print "Start process: ", index
    time.sleep(3)
    print "End process", index
 
 
pool = Pool(processes=3)
for i in xrange(4):
    pool.apply_async(function, (i,))

print "Started processes"
pool.close()
pool.join()
print "Subprocess done."


Start process:  1
Start process:  0
Start process:  2
Started processes
End process 0
End process 2
End process 1
Start process:  3
End process 3
Subprocess done.

正则表达式


In [12]:
s = r"<html><body><h1>hello world</h1></body></html>"

In [13]:
start = s.find("<h1>")
end = s.find("</h1>")
print s[start+4:end]


hello world

In [15]:
import re
help(re)


Help on module re:

NAME
    re - Support for regular expressions (RE).

FILE
    /Users/heming03/python-env/lib/python2.7/re.py

DESCRIPTION
    This module provides regular expression matching operations similar to
    those found in Perl.  It supports both 8-bit and Unicode strings; both
    the pattern and the strings being processed can contain null bytes and
    characters outside the US ASCII range.
    
    Regular expressions can contain both special and ordinary characters.
    Most ordinary characters, like "A", "a", or "0", are the simplest
    regular expressions; they simply match themselves.  You can
    concatenate ordinary characters, so last matches the string 'last'.
    
    The special characters are:
        "."      Matches any character except a newline.
        "^"      Matches the start of the string.
        "$"      Matches the end of the string or just before the newline at
                 the end of the string.
        "*"      Matches 0 or more (greedy) repetitions of the preceding RE.
                 Greedy means that it will match as many repetitions as possible.
        "+"      Matches 1 or more (greedy) repetitions of the preceding RE.
        "?"      Matches 0 or 1 (greedy) of the preceding RE.
        *?,+?,?? Non-greedy versions of the previous three special characters.
        {m,n}    Matches from m to n repetitions of the preceding RE.
        {m,n}?   Non-greedy version of the above.
        "\\"     Either escapes special characters or signals a special sequence.
        []       Indicates a set of characters.
                 A "^" as the first character indicates a complementing set.
        "|"      A|B, creates an RE that will match either A or B.
        (...)    Matches the RE inside the parentheses.
                 The contents can be retrieved or matched later in the string.
        (?iLmsux) Set the I, L, M, S, U, or X flag for the RE (see below).
        (?:...)  Non-grouping version of regular parentheses.
        (?P<name>...) The substring matched by the group is accessible by name.
        (?P=name)     Matches the text matched earlier by the group named name.
        (?#...)  A comment; ignored.
        (?=...)  Matches if ... matches next, but doesn't consume the string.
        (?!...)  Matches if ... doesn't match next.
        (?<=...) Matches if preceded by ... (must be fixed length).
        (?<!...) Matches if not preceded by ... (must be fixed length).
        (?(id/name)yes|no) Matches yes pattern if the group with id/name matched,
                           the (optional) no pattern otherwise.
    
    The special sequences consist of "\\" and a character from the list
    below.  If the ordinary character is not on the list, then the
    resulting RE will match the second character.
        \number  Matches the contents of the group of the same number.
        \A       Matches only at the start of the string.
        \Z       Matches only at the end of the string.
        \b       Matches the empty string, but only at the start or end of a word.
        \B       Matches the empty string, but not at the start or end of a word.
        \d       Matches any decimal digit; equivalent to the set [0-9].
        \D       Matches any non-digit character; equivalent to the set [^0-9].
        \s       Matches any whitespace character; equivalent to [ \t\n\r\f\v].
        \S       Matches any non-whitespace character; equiv. to [^ \t\n\r\f\v].
        \w       Matches any alphanumeric character; equivalent to [a-zA-Z0-9_].
                 With LOCALE, it will match the set [0-9_] plus characters defined
                 as letters for the current locale.
        \W       Matches the complement of \w.
        \\       Matches a literal backslash.
    
    This module exports the following functions:
        match    Match a regular expression pattern to the beginning of a string.
        search   Search a string for the presence of a pattern.
        sub      Substitute occurrences of a pattern found in a string.
        subn     Same as sub, but also return the number of substitutions made.
        split    Split a string by the occurrences of a pattern.
        findall  Find all occurrences of a pattern in a string.
        finditer Return an iterator yielding a match object for each match.
        compile  Compile a pattern into a RegexObject.
        purge    Clear the regular expression cache.
        escape   Backslash all non-alphanumerics in a string.
    
    Some of the functions in this module takes flags as optional parameters:
        I  IGNORECASE  Perform case-insensitive matching.
        L  LOCALE      Make \w, \W, \b, \B, dependent on the current locale.
        M  MULTILINE   "^" matches the beginning of lines (after a newline)
                       as well as the string.
                       "$" matches the end of lines (before a newline) as well
                       as the end of the string.
        S  DOTALL      "." matches any character at all, including the newline.
        X  VERBOSE     Ignore whitespace and comments for nicer looking RE's.
        U  UNICODE     Make \w, \W, \b, \B, dependent on the Unicode locale.
    
    This module also defines an exception 'error'.

CLASSES
    exceptions.Exception(exceptions.BaseException)
        sre_constants.error
    
    class error(exceptions.Exception)
     |  Method resolution order:
     |      error
     |      exceptions.Exception
     |      exceptions.BaseException
     |      __builtin__.object
     |  
     |  Data descriptors defined here:
     |  
     |  __weakref__
     |      list of weak references to the object (if defined)
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from exceptions.Exception:
     |  
     |  __init__(...)
     |      x.__init__(...) initializes x; see help(type(x)) for signature
     |  
     |  ----------------------------------------------------------------------
     |  Data and other attributes inherited from exceptions.Exception:
     |  
     |  __new__ = <built-in method __new__ of type object>
     |      T.__new__(S, ...) -> a new object with type S, a subtype of T
     |  
     |  ----------------------------------------------------------------------
     |  Methods inherited from exceptions.BaseException:
     |  
     |  __delattr__(...)
     |      x.__delattr__('name') <==> del x.name
     |  
     |  __getattribute__(...)
     |      x.__getattribute__('name') <==> x.name
     |  
     |  __getitem__(...)
     |      x.__getitem__(y) <==> x[y]
     |  
     |  __getslice__(...)
     |      x.__getslice__(i, j) <==> x[i:j]
     |      
     |      Use of negative indices is not supported.
     |  
     |  __reduce__(...)
     |  
     |  __repr__(...)
     |      x.__repr__() <==> repr(x)
     |  
     |  __setattr__(...)
     |      x.__setattr__('name', value) <==> x.name = value
     |  
     |  __setstate__(...)
     |  
     |  __str__(...)
     |      x.__str__() <==> str(x)
     |  
     |  __unicode__(...)
     |  
     |  ----------------------------------------------------------------------
     |  Data descriptors inherited from exceptions.BaseException:
     |  
     |  __dict__
     |  
     |  args
     |  
     |  message

FUNCTIONS
    compile(pattern, flags=0)
        Compile a regular expression pattern, returning a pattern object.
    
    escape(pattern)
        Escape all non-alphanumeric characters in pattern.
    
    findall(pattern, string, flags=0)
        Return a list of all non-overlapping matches in the string.
        
        If one or more groups are present in the pattern, return a
        list of groups; this will be a list of tuples if the pattern
        has more than one group.
        
        Empty matches are included in the result.
    
    finditer(pattern, string, flags=0)
        Return an iterator over all non-overlapping matches in the
        string.  For each match, the iterator returns a match object.
        
        Empty matches are included in the result.
    
    match(pattern, string, flags=0)
        Try to apply the pattern at the start of the string, returning
        a match object, or None if no match was found.
    
    purge()
        Clear the regular expression cache
    
    search(pattern, string, flags=0)
        Scan through string looking for a match to the pattern, returning
        a match object, or None if no match was found.
    
    split(pattern, string, maxsplit=0, flags=0)
        Split the source string by the occurrences of the pattern,
        returning a list containing the resulting substrings.
    
    sub(pattern, repl, string, count=0, flags=0)
        Return the string obtained by replacing the leftmost
        non-overlapping occurrences of the pattern in string by the
        replacement repl.  repl can be either a string or a callable;
        if a string, backslash escapes in it are processed.  If it is
        a callable, it's passed the match object and must return
        a replacement string to be used.
    
    subn(pattern, repl, string, count=0, flags=0)
        Return a 2-tuple containing (new_string, number).
        new_string is the string obtained by replacing the leftmost
        non-overlapping occurrences of the pattern in the source
        string by the replacement repl.  number is the number of
        substitutions that were made. repl can be either a string or a
        callable; if a string, backslash escapes in it are processed.
        If it is a callable, it's passed the match object and must
        return a replacement string to be used.
    
    template(pattern, flags=0)
        Compile a template pattern, returning a pattern object

DATA
    DOTALL = 16
    I = 2
    IGNORECASE = 2
    L = 4
    LOCALE = 4
    M = 8
    MULTILINE = 8
    S = 16
    U = 32
    UNICODE = 32
    VERBOSE = 64
    X = 64
    __all__ = ['match', 'search', 'sub', 'subn', 'split', 'findall', 'comp...
    __version__ = '2.2.1'

VERSION
    2.2.1



In [16]:
# 导入库
import re

In [17]:
p1 = r".*<h1>(.*?)</h1>.*"
pattern = re.compile(p1)
groups = re.match(pattern, s)
print groups.group(1)


hello world

In [18]:
name="Hello,My name is tiger,nice to meet you..."
k=re.search(r't(ige)r',name)
if k:
    print k.group(0),k.group(1)
else:
    print "not search!"


tiger ige

In [20]:
name="Hello,My name is tiger,nice to meet you..."
k=re.match(r"H(....)", name)
if k:
    print k.group(0),'\n',k.group(1)
else:
    print "not match!"


Hello 
ello

查找所有 FindAll & FindIter


In [21]:
mail='<user01@mail.com> <user02@mail.com> user04@mail.com'
re.findall(r'(\w+@m....[a-z]{3})', mail)


Out[21]:
['user01@mail.com', 'user02@mail.com', 'user04@mail.com']

In [26]:
mail_list_iter = re.finditer(r'(\w+@m....[a-z]{3})', mail)

In [27]:
for i in mail_list_iter:
    print type(i)
    print i.group()


<type '_sre.SRE_Match'>
user01@mail.com
<type '_sre.SRE_Match'>
user02@mail.com
<type '_sre.SRE_Match'>
user04@mail.com

替换


In [28]:
help(re.sub)


Help on function sub in module re:

sub(pattern, repl, string, count=0, flags=0)
    Return the string obtained by replacing the leftmost
    non-overlapping occurrences of the pattern in string by the
    replacement repl.  repl can be either a string or a callable;
    if a string, backslash escapes in it are processed.  If it is
    a callable, it's passed the match object and must return
    a replacement string to be used.


In [29]:
test="Hi, nice to meet you where are you from?"
re.sub(r'\s','-',test)


Out[29]:
'Hi,-nice-to-meet-you-where-are-you-from?'

In [30]:
re.sub(r'\s','-',test, 3)


Out[30]:
'Hi,-nice-to-meet you where are you from?'

In [31]:
help(re.subn)


Help on function subn in module re:

subn(pattern, repl, string, count=0, flags=0)
    Return a 2-tuple containing (new_string, number).
    new_string is the string obtained by replacing the leftmost
    non-overlapping occurrences of the pattern in the source
    string by the replacement repl.  number is the number of
    substitutions that were made. repl can be either a string or a
    callable; if a string, backslash escapes in it are processed.
    If it is a callable, it's passed the match object and must
    return a replacement string to be used.


In [32]:
re.subn(r'\s','-',test, 3)


Out[32]:
('Hi,-nice-to-meet you where are you from?', 3)

分隔字符串


In [33]:
test="Hi, nice to meet you where are you from?"
re.split(r"\s+",test)


Out[33]:
['Hi,', 'nice', 'to', 'meet', 'you', 'where', 'are', 'you', 'from?']

In [34]:
re.split(r"\s+",test,3)


Out[34]:
['Hi,', 'nice', 'to', 'meet you where are you from?']

In [ ]: