我正在使用模塊通過命令行使用創建地址對象。但是當我給它提供無效的參數(即那些應該引發異常的參數)時,不會引發異常。更糟的是,沒有記錄(除非我創建一個有效的對象)。爲什麼argparse不會引發異常?
所以,這個工程:
-n Patrick -a "151 Piedmont Ave" -c "Winston Salem" -s "NC" -z 27101
這不:
-l ERROR -n Patrick -a "151 Piedmont Ave" -c "Winston Salem" -s "NC" -z 271
我要去哪裏錯了?
注:這是家庭作業,所以絕對答案的指導將不勝感激。
"""
property_address.py
"""
import re
import logging
import argparse
LOG_FILENAME = 'property_address.log'
LOG_FORMAT = "%(asctime)s - %(levelname)s - %(funcName)s - %(message)s"
DEFAULT_LOG_LEVEL = "debug"
LEVELS = {'debug': logging.DEBUG,
'info': logging.INFO,
'warning': logging.WARNING,
'error': logging.ERROR,
'critical': logging.CRITICAL
}
def start_logging(filename=LOG_FILENAME, level=None):
logging.basicConfig(filename=filename, level=level, filemode='w', format=LOG_FORMAT)
logging.info('Starting up the property address program')
class ZipCodeError(Exception):
"Custom exception for invalid zip codes."
pass
class StateError(Exception):
"Custom exception for invalid state abbreviation."
pass
class Address(object):
"""
An address object.
"""
def __init__(self, name, street_address, city, state, zip_code):
self._name = name
self._street_address = street_address
self._city = city
self._state = state
self._zip_code = zip_code
logging.info('Instantiated an address')
@property
def name(self):
return self._name
@property
def street_address(self):
return self._street_address
@property
def city(self):
return self._city
@property
def state(self):
return self._state
@state.setter
def state(self, value):
"Validate that states are abbreviated as US Postal style."
state_valid = re.compile(r'[A-Z]{2}$')
if re.match(state_valid, value):
self._state = value
else:
message = 'STATE Exception: State not in correct format'
logging.error(message)
raise StateError()
@property
def zip_code(self):
return self._zip_code
@zip_code.setter
def zip_code(self, value):
"Validate zip codes are five digits."
zip_valid = re.compile(r'\d{5}$')
if re.match(zip_valid, value):
self._zip_code = value
else:
message = 'ZIP CODE Exception: Zip code not in correct format'
logging.error(message)
raise ZipCodeError()
def __str__(self):
return self._name
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Set attributes for property address.')
parser.add_argument(
'-l',
'--level',
dest='level',
choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'],
default='INFO',
help='Sets the log level to DEBUG, INFO, WARNING, ERROR, and CRITICAL')
parser.add_argument(
'-n',
'--name',
dest='name',
action='store',
required=True,
help='Sets the name value of the Address object')
parser.add_argument(
'-a',
'--address',
dest='address',
action='store',
required=True,
help='Sets the street_address value of the Address object')
parser.add_argument(
'-c',
'--city',
dest='city',
action='store',
required=True,
help='Sets the city value of the Address object')
parser.add_argument(
'-s',
'--state',
dest='state',
action='store',
required=True,
help='Sets the state value of the Address object')
parser.add_argument(
'-z',
'--zip_code',
dest='zip_code',
action='store',
required=True,
help='Sets the zip_code value of the Address object')
args = parser.parse_args()
# Start our logger
start_logging(level=(args.level))
# Create our Address object
a = Address(args.name, args.address, args.city, args.state, args.zip_code)
爲什麼不測試郵政編碼作爲參數的一部分;見例如http://stackoverflow.com/q/25470844/3001761 – jonrsharpe 2014-12-13 12:56:12
這是有道理的。但爲什麼我的例外不是首先被提出? – 2014-12-13 13:11:10
因爲在'Address .__ init__'你分配給'self._zip_code',繞過setter,而不是'self.zip_code'。 – jonrsharpe 2014-12-13 13:12:25