我正在尝试使用cutplace中的API来构建自定义检查 http://cutplace.sourceforge.net/api.html#writing-checks
使用附带的演示数据和代码,我尝试按照手册进行操作,至少直到它突然结束。
useCutplace.py:
# Validate a test CSV file.
import os.path
from cutplace import interface
from cutplace import checks
from cutplace import ranges
class FullNameLengthIsInRangeCheck(checks.AbstractCheck):
"""Check that total length of customer name is within the specified range."""
def __init__(self, description, rule, availableFieldNames, location=None):
super(FullNameLengthIsInRangeCheck, self).__init__(description, rule, availableFieldNames, location)
self._fullNameRange = ranges.Range(rule)
self.reset()
def checkRow(self, rowMap, location):
fullName = rowMap["last_name"] + ", " + rowMap["first_name"]
fullNameLength = len(fullName)
try:
self._fullNameRange.validate("full name", fullNameLength)
except ranges.RangeValueError, error:
raise CheckError("full name length is %d but must be in range %s: %r" \
% (fullNameLength, self._fullNameRange, fullName))
icdPath = os.path.join("icd_customers_field_names_only.csv")
dataPath = os.path.join("customers.csv")
icd = interface.InterfaceControlDocument()
icd.read(icdPath)
for row in interface.validatedRows(icd, dataPath):
print row
带有自定义检查的界面控制文档:
,Interface: customers,
,,
,Data format,
D,Format,CSV
D,Header,1
,,
,Fields,
,Name,
F,branch_id,
F,customer_id,
F,first_name,
F,surname,
F,gender,
F,date_of_birth,
C,"full name must have at most 100 characters",FullNameLengthIsInRange,:100
customers.csv
Branch id,Customer id,First name,Surname,Gender,Date of birth
38000,16,Daisy,Mason,female,27.02.1946
38000,42,Wendy,Davis,female,30.12.1971
38000,57,Keith,Parker,male,02.06.1984
38000,76,Kenneth,Tucker,male,15.11.1908
38053,11,Carlos,Barrett,male,09.02.1929
38053,20,Terrance,Hart,male,11.03.1961
38053,34,Lori,Dunn,female,26.09.1996
38053,73,Mary,Sutton,female,09.12.1982
38053,83,Lorraine,Castro,female,15.08.1978
38111,16,Esther,Newman,female,23.03.1932
38111,79,Tyler,Rose,male,17.12.1920
38111,127,Andrew,Dixon,male,02.10.1913
错误
>python useCutplace.py
Traceback (most recent call last):
File "useCutplace.py", line 29, in <module>
icd.read(icdPath)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/cutplace-0.6.7-py2.6.egg/cutplace/interface.py", line 406, in read
self._processRow(icdRowToProcess)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/cutplace-0.6.7-py2.6.egg/cutplace/interface.py", line 363, in _processRow
self.addCheck(icdRowToProcess[1:])
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/cutplace-0.6.7-py2.6.egg/cutplace/interface.py", line 339, in addCheck
checkClass = self._createCheckClass(checkType)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/cutplace-0.6.7-py2.6.egg/cutplace/interface.py", line 171, in _createCheckClass
return self._createClass("checks", checkType, "Check", "check")
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/cutplace-0.6.7-py2.6.egg/cutplace/interface.py", line 162, in _createClass
raise fields.FieldSyntaxError("cannot find %s: %s" % (typeName, str(type)), self._location)
cutplace.fields.FieldSyntaxError: icd_customers_field_names_only.csv (R16C1): cannot find check: FullNameLengthIsInRange
答案 0 :(得分:1)
从版本0.7.0开始,cutplace支持插件。只需将您自己的支票存储在单独的Python模块中,然后使用命令行选项--plugins
指定模块所在的文件夹。然后,Cutplace将导入并初始化插件文件夹中的任何Python模块。
本文档的API章节包含有关如何执行此操作的详细示例。
答案 1 :(得分:0)
好的诀窍是:
把类放在一个单独的模块中,我在这里称之为mychecks.py
from cutplace import checks
from cutplace import ranges
class FullNameLengthIsInRangeCheck(checks.AbstractCheck):
"""Check that total length of customer name is within the specified range."""
def __init__(self, description, rule, availableFieldNames, location=None):
super(FullNameLengthIsInRangeCheck, self).__init__(description, rule, availableFieldNames, location)
self._fullNameRange = ranges.Range(rule)
self.reset()
def checkRow(self, rowMap, location):
fullName = rowMap["surname"] + ", " + rowMap["first_name"]
fullNameLength = len(fullName)
try:
self._fullNameRange.validate("full name", fullNameLength)
except ranges.RangeValueError, error:
raise checks.CheckError("full name length is %d but must be in range %s: %r" \
% (fullNameLength, self._fullNameRange, fullName))
在icd中明确命名该模块:
,Interface: customers,
,,
,Data format,
D,Format,CSV
D,Header,1
,,
,Fields,
,Name,
F,branch_id,
F,customer_id,
F,first_name,
F,surname,
F,gender,
F,date_of_birth,
C,"full name must have at most 100 characters",mychecks.FullNameLengthIsInRange,:10
模块必须位于PYTHONPATH或直接目录中。您似乎无法创建包含cutplace可以看到的模块的包。