- 浏览: 2555984 次
- 性别:
- 来自: 成都
文章分类
最新评论
-
nation:
你好,在部署Mesos+Spark的运行环境时,出现一个现象, ...
Spark(4)Deal with Mesos -
sillycat:
AMAZON Relatedhttps://www.godad ...
AMAZON API Gateway(2)Client Side SSL with NGINX -
sillycat:
sudo usermod -aG docker ec2-use ...
Docker and VirtualBox(1)Set up Shared Disk for Virtual Box -
sillycat:
Every Half an Hour30 * * * * /u ...
Build Home NAS(3)Data Redundancy -
sillycat:
3 List the Cron Job I Have>c ...
Build Home NAS(3)Data Redundancy
DiveIntoPython(十五)
英文书地址:
http://diveintopython.org/toc/index.html
Chapter 16.Functional Progamming
16.1.Diving in
The following is a complete Python program that acts as a cheap and simple regression testing framework. It takes unit tests that you've written for individual modules, collects them all into one big test suite, and runs them all at once.
example 16.1.regression.py
import sys, os, re, unittest
def regressionTest():
path = os.path.abspath(os.path.dirname(sys.argv[0]))
files = os.listdir(path)
test = re.compile("test\.py$", re.IGNORECASE)
files = filter(test.search, files)
filenameToModuleName = lambda f: os.path.splitext(f)[0]
moduleNames = map(filenameToModuleName, files)
modules = map(__import__, moduleNames)
load = unittest.defaultTestLoader.loadTestsFromModule
return unittest.TestSuite(map(load, modules))
if __name__ == "__main__":
unittest.main(defaultTest="regressionTest")
example 16.2.Sample output of regression.py
E:\book\opensource\python\diveintopython-5.4\py>python regression.py -v
info should fail with no object ... ok
info should return known result for apihelper ... ok
info should honor collapse argument ... ok
info should honor spacing argument ... ok
...snip...
fromRoman(toRoman(n))==n for all n ... ok
toRoman should fail with non-integer input ... ok
toRoman should fail with negative input ... ok
toRoman should fail with large input ... ok
toRoman should fail with 0 input ... ok
soundex should give known result with known input ... ok
----------------------------------------------------------------------
Ran 81 tests in 0.593s
OK
16.2.Finding the path
When running Python scripts from the command line, it is sometimes useful to know where the currently running script is located on disk.
The key to it is sys.argv. As you saw in Chapter 9, XML Processing, this is a list that holds the list of command-line arguments. However, it also holds the name of the running script, exactly as it was called from the command line, and this is enough information to determine its location.
example 16.3.fullpath.py
import sys, os
print 'sys.argv[0] =', sys.argv[0]
pathname = os.path.dirname(sys.argv[0])
print 'path =', pathname
print 'full path =', os.path.abspath(pathname)
Regardless of how you run a script, sys.argv[0] will always contain the name of the script, exactly as it appears on the command line. This may or may not include any path information, as you'll see shortly.
os.path.dirname takes a filename as a string and returns the directory path portion. If the given filename does not include any path information, os.path.dirname returns an empty string.
os.path.abspath is the key here. It takes a pathname, which can be partial or even blank, and returns a fully qualified pathname.
example 16.4.Further explanation of os.path.abspath
>>> import os
>>> os.getcwd()
'E:\\book\\opensource\\python\\diveintopython-5.4\\py'
>>> os.path.abspath('')
'E:\\book\\opensource\\python\\diveintopython-5.4\\py'
>>> os.path.abspath('.ssh')
'E:\\book\\opensource\\python\\diveintopython-5.4\\py\\.ssh'
>>> os.path.abspath('E:\\book\\opensource\\python\\diveintopython-5.4\\py\\.ssh')
'E:\\book\\opensource\\python\\diveintopython-5.4\\py\\.ssh'
>>> os.path.abspath('.ssh/../foo/')
'E:\\book\\opensource\\python\\diveintopython-5.4\\py\\foo'
os.getcwd() returns the current working directory.
Calling os.path.abspath with an empty string returns the current working directory, same as os.getcwd().
It normalizes the path by making it as simple as possible. If you just want to normalize a pathname like this without turning it into a full pathname, use os.path.normpath instead.
example 16.5.Sample output from fullpath.py
E:\book\opensource\python\diveintopython-5.4\py>python fullpath.py
sys.argv[0] = fullpath.py
path =
full path = E:\book\opensource\python\diveintopython-5.4\py
E:\>python E:\book\opensource\python\diveintopython-5.4\py\fullpath.py
sys.argv[0] = E:\book\opensource\python\diveintopython-5.4\py\fullpath.py
path = E:\book\opensource\python\diveintopython-5.4\py
full path = E:\book\opensource\python\diveintopython-5.4\py
If the script is run from the current directory without giving any path, os.path.dirname will simply return an empty string. Given an empty string, os.path.abspath returns the current directory, which is what you want, since the script was run from the current directory.
sys.argv[0] includes the full path of the script. You can then use the os.path.dirname function to strip off the script name and return the full directory name, and os.path.abspath simply returns what you give it.
example 16.6.Running scripts in the current directory
import sys, os, re, unittest
def regressionTest():
path = os.getcwd()
sys.path.append(path)
files = os.listdir(path)
Instead of setting path to the directory where the currently running script is located, you set it to the current working directory instead. This will be whatever directory you were in before you ran the script, which is not necessarily the same as the directory the script is in.
Append this directory to the Python library search path, so that when you dynamically import the unit test modules later, Python can find them. You didn't need to do this when path was the directory of the currently running script, because Python always looks in that directory.
The rest of the function is the same.
This technique will allow you to re-use this regression.py script on multiple projects. Just put the script in a common directory, then change to the project's directory before running it. All of that project's unit tests will be found and tested, instead of the unit tests in the common directory where regression.py is located.
16.3.Filtering lists revisited
Python has a built-in filter function which takes two arguments, a function and a list, and returns a list.
The function passed as the first argument to filter must itself take one argument, and the list that filter returns will contain all the elements from the list passed to filter for which the function passed to filter returns true.
example 16.7.Introducing filter
>>> def odd(n):
... return n % 2
...
>>> li = [1,2,3,5,9,10,256,-3]
>>> filter(odd,li)
[1, 3, 5, 9, -3]
>>> [e for e in li if odd(e)]
[1, 3, 5, 9, -3]
>>> filteredList = []
>>> for n in li:
... if odd(n):
... filteredList.append(n)
...
>>> filteredList
[1, 3, 5, 9, -3]
odd uses the built-in mod function “%” to return True if n is odd and False if n is even.
filter takes two arguments, a function (odd) and a list (li). It loops through the list and calls odd with each element. If odd returns a true value (remember, any non-zero value is true in Python), then the element is included in the returned list, otherwise it is filtered out. The result is a list of only the odd numbers from the original list, in the same order as they appeared in the original.
example 16.8.filter in regression.py
files = os.listdir(path)
test = re.compile("test\.py$", re.IGNORECASE)
files = filter(test.search, files)
Either way, files will end up with the names of the files in the same directory as this script you're running.
If the regular expression matches, the method will return a Match object, which Python considers to be true, so the element will be included in the list returned by filter. If the regular expression does not match, the search method will return None, which Python considers to be false, so the element will not be included.
example 16.9.Filtering using list comprehensions instead
files = os.listdir(path)
test = re.compile("test\.py$", re.IGNORECASE)
files = [f for f in files if test.search(f)]
>>> files = os.listdir("")
>>> test = re.compile("test\.py$", re.IGNORECASE)
>>> files = [f for f in files if test.search(f)]
>>> files
['apihelpertest.py', 'kgptest.py', 'odbchelpertest.py', 'pluraltest.py', 'romantest.py', 'soundextest.py']
16.4.Mapping lists revisited
You're already familiar with using list comprehensions to map one list into another. There is another way to accomplish the same thing, using the built-in map function. It works much the same way as the filter function.
example 16.10.Introducing map
>>> def double(n):
... return n*2
...
>>> li = [1,2,3,5,9,10,256,-3]
>>> map(double,li)
[2, 4, 6, 10, 18, 20, 512, -6]
>>> [double(n) for n in li]
[2, 4, 6, 10, 18, 20, 512, -6]
>>> newList = []
>>> for n in li:
... newList.append(double(n))
...
>>> newList
[2, 4, 6, 10, 18, 20, 512, -6]
map takes a function and a list[8] and returns a new list by calling the function with each element of the list in order. In this case, the function simply multiplies each element by 2.
example 16.11.map with lists of mixed datatypes
>>> li = [5,'a',(2,'b')]
>>> map(double,li)
[10, 'aa', (2, 'b', 2, 'b')]
As a side note, I'd like to point out that map works just as well with lists of mixed datatypes, as long as the function you're using correctly handles each type.
example 16.12.map in regression.py
filenameToModuleName = lambda f: os.path.splitext(f)[0]
moduleNames = map(filenameToModuleName, files)
And as you saw in Example 6.17, “Splitting Pathnames”, os.path.splitext takes a filename and returns a tuple (name, extension). So filenameToModuleName is a function which will take a filename and strip off the file extension, and return just the name.
Calling map takes each filename listed in files, passes it to the function filenameToModuleName, and returns a list of the return values of each of those function calls. In other words, you strip the file extension off of each filename, and store the list of all those stripped filenames in moduleNames.
16.5.Data-centric programming
16.6.Dynamically importing modules
example 16.13.Importing multiple modules at once
import sys,os,re,unittest
This imports four modules at once: sys (for system functions and access to the command line parameters), os (for operating system functions like directory listings), re (for regular expressions), and unittest (for unit testing).
example 16.14.Importing modules dynamically
>>> sys = __import__('sys')
>>> os = __import__('os')
>>> re = __import__('re')
>>> unittest = __import__('unittest')
>>> sys
<module 'sys' (built-in)>
>>> os
<module 'os' from 'C:\Python26\lib\os.pyc'>
The built-in __import__ function accomplishes the same goal as using the import statement, but it's an actual function, and it takes a string as an argument.
example 16.15.Importing a list of modules dynamically
>>> moduleNames
['sys', 'os', 're', 'unittest']
>>> modules = map(__import__,moduleNames)
>>> modules
[<module 'sys' (built-in)>, <module 'os' from 'C:\Python26\lib\os.pyc'>, <module 're' from 'C:\Python26\lib\re.pyc'>, <module 'unittest' from 'C:\Python26\lib\unittest.pyc'>]
>>> modules[0].version
'2.6.4 (r264:75706, Jan 22 2010, 16:41:54) [MSC v.1500 32 bit (Intel)]'
>>> import sys
>>> sys.version
'2.6.4 (r264:75706, Jan 22 2010, 16:41:54) [MSC v.1500 32 bit (Intel)]'
Surprise, you wanted to import them, and you did, by mapping the __import__ function onto the list. Remember, this takes each element of the list (moduleNames) and calls the function (__import__) over and over, once with each element of the list, builds a list of the return values, and returns the result.
16.7.Putting it all together
example 16.16.The regressionTest function
def regressionTest():
path = os.path.abspath(os.path.dirname(sys.argv[0]))
files = os.listdir(path)
test = re.compile("test\.py$", re.IGNORECASE)
files = filter(test.search, files)
filenameToModuleName = lambda f: os.path.splitext(f)[0]
moduleNames = map(filenameToModuleName, files)
modules = map(__import__, moduleNames)
load = unittest.defaultTestLoader.loadTestsFromModule
return unittest.TestSuite(map(load, modules))
example 16.7.Step 1:Get all the files
>>> import sys,os,re,unittest
>>> path = r'E:\book\opensource\python\diveintopython-5.4\py'
>>> files = os.listdir(path)
>>> files
['apihelper.py', 'apihelper.pyc', 'apihelpertest.py', 'apihelpertest.pyc', 'argecho.py', 'autosize.py', 'BaseHTMLProcessor.py', 'BaseHTMLProcessor.pyc', 'builddialectexamples.py', 'colorize.py', 'dialect.py', 'fibonacci.py', 'fileinfo.py', 'fileinfo.pyc', 'fileinfo_fromdict.py', 'fullpath.py', 'kgp', 'kgptest.py', 'kgptest.pyc', 'LICENSE.txt', 'makerealworddoc.py', 'odbchelper.py', 'odbchelper.pyc', 'odbchelpertest.py', 'odbchelpertest.pyc', 'openanything.py', 'openanything.pyc', 'parsephone.py', 'piglatin.py', 'plural', 'plural-rules.en', 'plural.py', 'plural.pyc', 'pluraltest.py', 'pluraltest.pyc', 'pyfontify.py', 'regression.py', 'roman', 'roman.py', 'roman.pyc', 'romantest.py', 'romantest.pyc', 'search.py', 'soundex', 'soundex.py', 'soundex.pyc', 'soundextest.py', 'soundextest.pyc', 'statsout.py', 'statsout.pyc', 'temp.py', 'unicode2koi8r.py', 'urllister.py', 'urllister.pyc']
files is a list of all the files and directories in the script's directory.
example 16.18.Step 2:Filter to find the files you care about
>>> test = re.compile("test\.py$",re.IGNORECASE)
>>> files = filter(test.search,files)
>>> files
['apihelpertest.py', 'kgptest.py', 'odbchelpertest.py', 'pluraltest.py', 'romantest.py', 'soundextest.py']
This regular expression will match any string that ends with test.py. Note that you need to escape the period, since a period in a regular expression usually means “match any single character”, but you actually want to match a literal period instead.
example 16.19.Step 3:Map filenames to module names
>>> filenameToModuleName = lambda f:os.path.splitext(f)[0]
>>> filenameToModuleName('romantest.py')
'romantest'
>>> moduleNames = map(filenameToModuleName,files)
>>> moduleNames
['apihelpertest', 'kgptest', 'odbchelpertest', 'pluraltest', 'romantest', 'soundextest']
example 16.20.Step 4:Mapping module names to modules
>>> sys.path.append(r"E:\book\opensource\python\diveintopython-5.4\py")
>>> sys.path.append(r"E:\book\opensource\python\diveintopython-5.4\py\kgp")
>>> moduleNames
['apihelpertest', 'kgptest', 'odbchelpertest', 'pluraltest', 'romantest', 'soundextest']
>>> modules = map(__import__,moduleNames)
>>> modules
[<module 'apihelpertest' from 'E:\book\opensource\python\diveintopython-5.4\py\apihelpertest.pyc'>, <module 'kgptest' from 'E:\book\opensource\python\diveintopython-5.4\py\kgptest.pyc'>, <module 'odbchelpertest' from 'E:\book\opensource\python\diveintopython-5.4\py\odbchelpertest.pyc'>, <module 'pluraltest' from 'E:\book\opensource\python\diveintopython-5.4\py\pluraltest.pyc'>, <module 'romantest' from 'E:\book\opensource\python\diveintopython-5.4\py\romantest.pyc'>, <module 'soundextest' from 'E:\book\opensource\python\diveintopython-5.4\py\soundextest.pyc'>]
>>> modules[-1]
<module 'soundextest' from 'E:\book\opensource\python\diveintopython-5.4\py\soundextest.pyc'>
example 16.21.Step 5:Loading the modules into a test suite
>>> load = unittest.defaultTestLoader.loadTestsFromModule
>>> map(load,modules)
[<unittest.TestSuite tests=[<unittest.TestSuite tests=[<apihelpertest.BadInput testMethod=testNoObject>]>, <unittest.TestSuite tests=[<apihelpertest.KnownValues testMethod=testApiHelper>]>, <unittest.TestSuite tests=[<apihelpertest.ParamChecks testMethod=testCollapse>, <apihelpertest.ParamChecks testMethod=testSpacing>]>, <unittest.TestSuite tests=[]>]>, <unittest.TestSuite tests=[<unittest.TestSuite
...snip...
>>> unittest.TestSuite(map(load,modules))
That's what the loadTestsFromModule method does: it introspects into each module and returns a unittest.TestSuite object for each module. Each TestSuite object actually contains a list of TestSuite objects, one for each TestCase class in your module, and each of those TestSuite objects contains a list of tests, one for each test method in your module.
Finally, you wrap the list of TestSuite objects into one big test suite. The unittest module has no problem traversing this tree of nested test suites within test suites; eventually it gets down to an individual test method and executes it, verifies that it passes or fails, and moves on to the next one.
example 16.22.Step 6:Telling unittest to use your test suite
if __name__ == "__main__":
unittest.main(defaultTest="regressionTest")
英文书地址:
http://diveintopython.org/toc/index.html
Chapter 16.Functional Progamming
16.1.Diving in
The following is a complete Python program that acts as a cheap and simple regression testing framework. It takes unit tests that you've written for individual modules, collects them all into one big test suite, and runs them all at once.
example 16.1.regression.py
import sys, os, re, unittest
def regressionTest():
path = os.path.abspath(os.path.dirname(sys.argv[0]))
files = os.listdir(path)
test = re.compile("test\.py$", re.IGNORECASE)
files = filter(test.search, files)
filenameToModuleName = lambda f: os.path.splitext(f)[0]
moduleNames = map(filenameToModuleName, files)
modules = map(__import__, moduleNames)
load = unittest.defaultTestLoader.loadTestsFromModule
return unittest.TestSuite(map(load, modules))
if __name__ == "__main__":
unittest.main(defaultTest="regressionTest")
example 16.2.Sample output of regression.py
E:\book\opensource\python\diveintopython-5.4\py>python regression.py -v
info should fail with no object ... ok
info should return known result for apihelper ... ok
info should honor collapse argument ... ok
info should honor spacing argument ... ok
...snip...
fromRoman(toRoman(n))==n for all n ... ok
toRoman should fail with non-integer input ... ok
toRoman should fail with negative input ... ok
toRoman should fail with large input ... ok
toRoman should fail with 0 input ... ok
soundex should give known result with known input ... ok
----------------------------------------------------------------------
Ran 81 tests in 0.593s
OK
16.2.Finding the path
When running Python scripts from the command line, it is sometimes useful to know where the currently running script is located on disk.
The key to it is sys.argv. As you saw in Chapter 9, XML Processing, this is a list that holds the list of command-line arguments. However, it also holds the name of the running script, exactly as it was called from the command line, and this is enough information to determine its location.
example 16.3.fullpath.py
import sys, os
print 'sys.argv[0] =', sys.argv[0]
pathname = os.path.dirname(sys.argv[0])
print 'path =', pathname
print 'full path =', os.path.abspath(pathname)
Regardless of how you run a script, sys.argv[0] will always contain the name of the script, exactly as it appears on the command line. This may or may not include any path information, as you'll see shortly.
os.path.dirname takes a filename as a string and returns the directory path portion. If the given filename does not include any path information, os.path.dirname returns an empty string.
os.path.abspath is the key here. It takes a pathname, which can be partial or even blank, and returns a fully qualified pathname.
example 16.4.Further explanation of os.path.abspath
>>> import os
>>> os.getcwd()
'E:\\book\\opensource\\python\\diveintopython-5.4\\py'
>>> os.path.abspath('')
'E:\\book\\opensource\\python\\diveintopython-5.4\\py'
>>> os.path.abspath('.ssh')
'E:\\book\\opensource\\python\\diveintopython-5.4\\py\\.ssh'
>>> os.path.abspath('E:\\book\\opensource\\python\\diveintopython-5.4\\py\\.ssh')
'E:\\book\\opensource\\python\\diveintopython-5.4\\py\\.ssh'
>>> os.path.abspath('.ssh/../foo/')
'E:\\book\\opensource\\python\\diveintopython-5.4\\py\\foo'
os.getcwd() returns the current working directory.
Calling os.path.abspath with an empty string returns the current working directory, same as os.getcwd().
It normalizes the path by making it as simple as possible. If you just want to normalize a pathname like this without turning it into a full pathname, use os.path.normpath instead.
example 16.5.Sample output from fullpath.py
E:\book\opensource\python\diveintopython-5.4\py>python fullpath.py
sys.argv[0] = fullpath.py
path =
full path = E:\book\opensource\python\diveintopython-5.4\py
E:\>python E:\book\opensource\python\diveintopython-5.4\py\fullpath.py
sys.argv[0] = E:\book\opensource\python\diveintopython-5.4\py\fullpath.py
path = E:\book\opensource\python\diveintopython-5.4\py
full path = E:\book\opensource\python\diveintopython-5.4\py
If the script is run from the current directory without giving any path, os.path.dirname will simply return an empty string. Given an empty string, os.path.abspath returns the current directory, which is what you want, since the script was run from the current directory.
sys.argv[0] includes the full path of the script. You can then use the os.path.dirname function to strip off the script name and return the full directory name, and os.path.abspath simply returns what you give it.
example 16.6.Running scripts in the current directory
import sys, os, re, unittest
def regressionTest():
path = os.getcwd()
sys.path.append(path)
files = os.listdir(path)
Instead of setting path to the directory where the currently running script is located, you set it to the current working directory instead. This will be whatever directory you were in before you ran the script, which is not necessarily the same as the directory the script is in.
Append this directory to the Python library search path, so that when you dynamically import the unit test modules later, Python can find them. You didn't need to do this when path was the directory of the currently running script, because Python always looks in that directory.
The rest of the function is the same.
This technique will allow you to re-use this regression.py script on multiple projects. Just put the script in a common directory, then change to the project's directory before running it. All of that project's unit tests will be found and tested, instead of the unit tests in the common directory where regression.py is located.
16.3.Filtering lists revisited
Python has a built-in filter function which takes two arguments, a function and a list, and returns a list.
The function passed as the first argument to filter must itself take one argument, and the list that filter returns will contain all the elements from the list passed to filter for which the function passed to filter returns true.
example 16.7.Introducing filter
>>> def odd(n):
... return n % 2
...
>>> li = [1,2,3,5,9,10,256,-3]
>>> filter(odd,li)
[1, 3, 5, 9, -3]
>>> [e for e in li if odd(e)]
[1, 3, 5, 9, -3]
>>> filteredList = []
>>> for n in li:
... if odd(n):
... filteredList.append(n)
...
>>> filteredList
[1, 3, 5, 9, -3]
odd uses the built-in mod function “%” to return True if n is odd and False if n is even.
filter takes two arguments, a function (odd) and a list (li). It loops through the list and calls odd with each element. If odd returns a true value (remember, any non-zero value is true in Python), then the element is included in the returned list, otherwise it is filtered out. The result is a list of only the odd numbers from the original list, in the same order as they appeared in the original.
example 16.8.filter in regression.py
files = os.listdir(path)
test = re.compile("test\.py$", re.IGNORECASE)
files = filter(test.search, files)
Either way, files will end up with the names of the files in the same directory as this script you're running.
If the regular expression matches, the method will return a Match object, which Python considers to be true, so the element will be included in the list returned by filter. If the regular expression does not match, the search method will return None, which Python considers to be false, so the element will not be included.
example 16.9.Filtering using list comprehensions instead
files = os.listdir(path)
test = re.compile("test\.py$", re.IGNORECASE)
files = [f for f in files if test.search(f)]
>>> files = os.listdir("")
>>> test = re.compile("test\.py$", re.IGNORECASE)
>>> files = [f for f in files if test.search(f)]
>>> files
['apihelpertest.py', 'kgptest.py', 'odbchelpertest.py', 'pluraltest.py', 'romantest.py', 'soundextest.py']
16.4.Mapping lists revisited
You're already familiar with using list comprehensions to map one list into another. There is another way to accomplish the same thing, using the built-in map function. It works much the same way as the filter function.
example 16.10.Introducing map
>>> def double(n):
... return n*2
...
>>> li = [1,2,3,5,9,10,256,-3]
>>> map(double,li)
[2, 4, 6, 10, 18, 20, 512, -6]
>>> [double(n) for n in li]
[2, 4, 6, 10, 18, 20, 512, -6]
>>> newList = []
>>> for n in li:
... newList.append(double(n))
...
>>> newList
[2, 4, 6, 10, 18, 20, 512, -6]
map takes a function and a list[8] and returns a new list by calling the function with each element of the list in order. In this case, the function simply multiplies each element by 2.
example 16.11.map with lists of mixed datatypes
>>> li = [5,'a',(2,'b')]
>>> map(double,li)
[10, 'aa', (2, 'b', 2, 'b')]
As a side note, I'd like to point out that map works just as well with lists of mixed datatypes, as long as the function you're using correctly handles each type.
example 16.12.map in regression.py
filenameToModuleName = lambda f: os.path.splitext(f)[0]
moduleNames = map(filenameToModuleName, files)
And as you saw in Example 6.17, “Splitting Pathnames”, os.path.splitext takes a filename and returns a tuple (name, extension). So filenameToModuleName is a function which will take a filename and strip off the file extension, and return just the name.
Calling map takes each filename listed in files, passes it to the function filenameToModuleName, and returns a list of the return values of each of those function calls. In other words, you strip the file extension off of each filename, and store the list of all those stripped filenames in moduleNames.
16.5.Data-centric programming
16.6.Dynamically importing modules
example 16.13.Importing multiple modules at once
import sys,os,re,unittest
This imports four modules at once: sys (for system functions and access to the command line parameters), os (for operating system functions like directory listings), re (for regular expressions), and unittest (for unit testing).
example 16.14.Importing modules dynamically
>>> sys = __import__('sys')
>>> os = __import__('os')
>>> re = __import__('re')
>>> unittest = __import__('unittest')
>>> sys
<module 'sys' (built-in)>
>>> os
<module 'os' from 'C:\Python26\lib\os.pyc'>
The built-in __import__ function accomplishes the same goal as using the import statement, but it's an actual function, and it takes a string as an argument.
example 16.15.Importing a list of modules dynamically
>>> moduleNames
['sys', 'os', 're', 'unittest']
>>> modules = map(__import__,moduleNames)
>>> modules
[<module 'sys' (built-in)>, <module 'os' from 'C:\Python26\lib\os.pyc'>, <module 're' from 'C:\Python26\lib\re.pyc'>, <module 'unittest' from 'C:\Python26\lib\unittest.pyc'>]
>>> modules[0].version
'2.6.4 (r264:75706, Jan 22 2010, 16:41:54) [MSC v.1500 32 bit (Intel)]'
>>> import sys
>>> sys.version
'2.6.4 (r264:75706, Jan 22 2010, 16:41:54) [MSC v.1500 32 bit (Intel)]'
Surprise, you wanted to import them, and you did, by mapping the __import__ function onto the list. Remember, this takes each element of the list (moduleNames) and calls the function (__import__) over and over, once with each element of the list, builds a list of the return values, and returns the result.
16.7.Putting it all together
example 16.16.The regressionTest function
def regressionTest():
path = os.path.abspath(os.path.dirname(sys.argv[0]))
files = os.listdir(path)
test = re.compile("test\.py$", re.IGNORECASE)
files = filter(test.search, files)
filenameToModuleName = lambda f: os.path.splitext(f)[0]
moduleNames = map(filenameToModuleName, files)
modules = map(__import__, moduleNames)
load = unittest.defaultTestLoader.loadTestsFromModule
return unittest.TestSuite(map(load, modules))
example 16.7.Step 1:Get all the files
>>> import sys,os,re,unittest
>>> path = r'E:\book\opensource\python\diveintopython-5.4\py'
>>> files = os.listdir(path)
>>> files
['apihelper.py', 'apihelper.pyc', 'apihelpertest.py', 'apihelpertest.pyc', 'argecho.py', 'autosize.py', 'BaseHTMLProcessor.py', 'BaseHTMLProcessor.pyc', 'builddialectexamples.py', 'colorize.py', 'dialect.py', 'fibonacci.py', 'fileinfo.py', 'fileinfo.pyc', 'fileinfo_fromdict.py', 'fullpath.py', 'kgp', 'kgptest.py', 'kgptest.pyc', 'LICENSE.txt', 'makerealworddoc.py', 'odbchelper.py', 'odbchelper.pyc', 'odbchelpertest.py', 'odbchelpertest.pyc', 'openanything.py', 'openanything.pyc', 'parsephone.py', 'piglatin.py', 'plural', 'plural-rules.en', 'plural.py', 'plural.pyc', 'pluraltest.py', 'pluraltest.pyc', 'pyfontify.py', 'regression.py', 'roman', 'roman.py', 'roman.pyc', 'romantest.py', 'romantest.pyc', 'search.py', 'soundex', 'soundex.py', 'soundex.pyc', 'soundextest.py', 'soundextest.pyc', 'statsout.py', 'statsout.pyc', 'temp.py', 'unicode2koi8r.py', 'urllister.py', 'urllister.pyc']
files is a list of all the files and directories in the script's directory.
example 16.18.Step 2:Filter to find the files you care about
>>> test = re.compile("test\.py$",re.IGNORECASE)
>>> files = filter(test.search,files)
>>> files
['apihelpertest.py', 'kgptest.py', 'odbchelpertest.py', 'pluraltest.py', 'romantest.py', 'soundextest.py']
This regular expression will match any string that ends with test.py. Note that you need to escape the period, since a period in a regular expression usually means “match any single character”, but you actually want to match a literal period instead.
example 16.19.Step 3:Map filenames to module names
>>> filenameToModuleName = lambda f:os.path.splitext(f)[0]
>>> filenameToModuleName('romantest.py')
'romantest'
>>> moduleNames = map(filenameToModuleName,files)
>>> moduleNames
['apihelpertest', 'kgptest', 'odbchelpertest', 'pluraltest', 'romantest', 'soundextest']
example 16.20.Step 4:Mapping module names to modules
>>> sys.path.append(r"E:\book\opensource\python\diveintopython-5.4\py")
>>> sys.path.append(r"E:\book\opensource\python\diveintopython-5.4\py\kgp")
>>> moduleNames
['apihelpertest', 'kgptest', 'odbchelpertest', 'pluraltest', 'romantest', 'soundextest']
>>> modules = map(__import__,moduleNames)
>>> modules
[<module 'apihelpertest' from 'E:\book\opensource\python\diveintopython-5.4\py\apihelpertest.pyc'>, <module 'kgptest' from 'E:\book\opensource\python\diveintopython-5.4\py\kgptest.pyc'>, <module 'odbchelpertest' from 'E:\book\opensource\python\diveintopython-5.4\py\odbchelpertest.pyc'>, <module 'pluraltest' from 'E:\book\opensource\python\diveintopython-5.4\py\pluraltest.pyc'>, <module 'romantest' from 'E:\book\opensource\python\diveintopython-5.4\py\romantest.pyc'>, <module 'soundextest' from 'E:\book\opensource\python\diveintopython-5.4\py\soundextest.pyc'>]
>>> modules[-1]
<module 'soundextest' from 'E:\book\opensource\python\diveintopython-5.4\py\soundextest.pyc'>
example 16.21.Step 5:Loading the modules into a test suite
>>> load = unittest.defaultTestLoader.loadTestsFromModule
>>> map(load,modules)
[<unittest.TestSuite tests=[<unittest.TestSuite tests=[<apihelpertest.BadInput testMethod=testNoObject>]>, <unittest.TestSuite tests=[<apihelpertest.KnownValues testMethod=testApiHelper>]>, <unittest.TestSuite tests=[<apihelpertest.ParamChecks testMethod=testCollapse>, <apihelpertest.ParamChecks testMethod=testSpacing>]>, <unittest.TestSuite tests=[]>]>, <unittest.TestSuite tests=[<unittest.TestSuite
...snip...
>>> unittest.TestSuite(map(load,modules))
That's what the loadTestsFromModule method does: it introspects into each module and returns a unittest.TestSuite object for each module. Each TestSuite object actually contains a list of TestSuite objects, one for each TestCase class in your module, and each of those TestSuite objects contains a list of tests, one for each test method in your module.
Finally, you wrap the list of TestSuite objects into one big test suite. The unittest module has no problem traversing this tree of nested test suites within test suites; eventually it gets down to an individual test method and executes it, verifies that it passes or fails, and moves on to the next one.
example 16.22.Step 6:Telling unittest to use your test suite
if __name__ == "__main__":
unittest.main(defaultTest="regressionTest")
发表评论
-
NodeJS12 and Zlib
2020-04-01 07:44 479NodeJS12 and Zlib It works as ... -
Traefik 2020(1)Introduction and Installation
2020-03-29 13:52 339Traefik 2020(1)Introduction and ... -
Private Registry 2020(1)No auth in registry Nginx AUTH for UI
2020-03-18 00:56 440Private Registry 2020(1)No auth ... -
Buffer in NodeJS 12 and NodeJS 8
2020-02-25 06:43 390Buffer in NodeJS 12 and NodeJS ... -
NodeJS ENV Similar to JENV and PyENV
2020-02-25 05:14 482NodeJS ENV Similar to JENV and ... -
Prometheus HA 2020(3)AlertManager Cluster
2020-02-24 01:47 426Prometheus HA 2020(3)AlertManag ... -
Serverless with NodeJS and TencentCloud 2020(5)CRON and Settings
2020-02-24 01:46 340Serverless with NodeJS and Tenc ... -
GraphQL 2019(3)Connect to MySQL
2020-02-24 01:48 252GraphQL 2019(3)Connect to MySQL ... -
GraphQL 2019(2)GraphQL and Deploy to Tencent Cloud
2020-02-24 01:48 454GraphQL 2019(2)GraphQL and Depl ... -
GraphQL 2019(1)Apollo Basic
2020-02-19 01:36 330GraphQL 2019(1)Apollo Basic Cl ... -
Serverless with NodeJS and TencentCloud 2020(4)Multiple Handlers and Running wit
2020-02-19 01:19 316Serverless with NodeJS and Tenc ... -
Serverless with NodeJS and TencentCloud 2020(3)Build Tree and Traverse Tree
2020-02-19 01:19 323Serverless with NodeJS and Tenc ... -
Serverless with NodeJS and TencentCloud 2020(2)Trigger SCF in SCF
2020-02-19 01:18 297Serverless with NodeJS and Tenc ... -
Serverless with NodeJS and TencentCloud 2020(1)Running with Component
2020-02-19 01:17 314Serverless with NodeJS and Tenc ... -
NodeJS MySQL Library and npmjs
2020-02-07 06:21 293NodeJS MySQL Library and npmjs ... -
Python Library 2019(1)requests and aiohttp
2019-12-18 01:12 264Python Library 2019(1)requests ... -
NodeJS Installation 2019
2019-10-20 02:57 577NodeJS Installation 2019 Insta ... -
Monitor Tool 2019(2)Monit on Multiple Instances and Email Alerts
2019-10-18 10:57 271Monitor Tool 2019(2)Monit on Mu ... -
Sqlite Database 2019(1)Sqlite3 Installation and Docker phpsqliteadmin
2019-09-05 11:24 379Sqlite Database 2019(1)Sqlite3 ... -
Supervisor 2019(2)Ubuntu and Multiple Services
2019-08-19 10:53 380Supervisor 2019(2)Ubuntu and Mu ...
相关推荐
Python是一种广泛使用的高级编程语言,以其简洁明了的语法和强大的功能而闻名。《深入Python3(中文版)》是一本系统介绍Python 3的书籍,旨在帮助读者深入学习Python 3的基本知识与应用。本文将根据给定文件的信息...
《Dive Into Python 3中文版》是一本深入学习Python 3编程语言的教程,适合初学者和有一定编程基础的开发者。这本书详细介绍了Python 3的各种特性,包括语法、数据结构、函数、类、模块、异常处理、输入/输出、网络...
《Dive into Python3》的压缩包文件名为diveintopython3-r860-2010-01-13,这可能表示它是2010年1月13日发布的第860个修订版。这个版本可能包含了作者对初版的修正和更新,以适应Python 3的最新发展。 通过阅读这...
PDF版本的《Dive Into Python 中文译文版》(diveintopython-pdfzh-cn-5.4b.zip)提供了完整的书籍内容,涵盖了Python的基础知识到高级特性。书中通过实际案例引导读者深入学习,包括但不限于变量、数据类型、控制...
《Dive Into Python》是一本深受编程初学者和有经验开发者喜爱的Python编程教程。这本书以其深入浅出的讲解方式,让学习者能够快速掌握Python编程语言的核心概念和实际应用,特别是对于想要涉足Web开发领域的读者,...
- **在线地址**:本书可通过官方网址http://diveintopython.org/(英文原版)及http://www.woodpecker.org.cn/diveintopython(中文版)获取。 - **版本更新**:建议通过官方渠道获取最新版本,确保内容的准确性和...
深入python,深入Python (Dive Into Python) 译者序 by limodou 主页(http://phprecord.126.com) Python论坛 本书英文名字为《Dive Into Python》,其发布遵守 GNU 的自由文档许可证(Free Document Lience)的...
dive into python英文原版,Dive Into Python 3 covers Python 3 and its differences from Python 2. Compared to Dive Into Python, it’s about 20% revised and 80% new material. The book is now complete, ...
《深入Python 3》是一本全面且深入介绍Python 3编程语言的电子书籍,旨在帮助读者从...压缩包中的文件“diveintomark-diveintopython3-793871b”很可能是该书的源代码或HTML文件,可以配合阅读,加深对书中示例的理解。
《Dive Into Python 2 中文版》是一本深度探讨Python编程语言的教程,适合已经有一定编程基础,希望深入理解Python特性和应用的读者。这本书以其详尽的解释和丰富的实例,为Python初学者和进阶者提供了全面的学习...
Dive Into Python 3 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
Didyoureadtheoriginal“DiveIntoPython”?Didyoubuyit onpaper?(Ifso,thanks!)AreyoureadytotaketheplungeintoPython3?…Ifso,readon.(Ifnoneofthat istrue,you’dbebetteroffstartingatthebeginning.) Python3...
在“diveintopython3-master”这个压缩包中,包含了这本书的所有源代码示例。通过这些代码,我们可以学习到以下关键知识点: 1. **Python基础**:包括变量、数据类型(如整型、浮点型、字符串、列表、元组、字典)...
《Dive Into Python V5.4》是一本深入学习Python编程语言的经典教程,以其详尽的解释和丰富的实例深受程序员们的喜爱。这个版本是官方提供的最新版本,它不仅包含了PDF格式的完整书籍,还附带了书中所有示例代码,为...
diveintopython-examples-5.4.rardiveintopython-examples-5.4.rardiveintopython-examples-5.4.rardiveintopython-examples-5.4.rar
《Dive Into Python3》和《深入Python3》是两本深受Python爱好者欢迎的书籍,分别提供了英文和中文的学习资源,旨在帮助读者全面理解和掌握Python3编程语言。这两本书覆盖了Python3的基础语法、高级特性以及实际应用...
Dive Into Python中文版,精心整理,epub版本方便阅读,下载阅读.
### Dive Into Python 3 中文版 - 安装Python 3 #### 标题解析 - **Dive Into Python 3 中文版**:这本书名表明了内容将深入讲解Python 3的各项特性和使用方法,适合希望深入了解Python 3编程语言的读者。 #### ...