在不重复代码的情况下检查 class 函数输入是否有效
Checking if class fucntion inputs are valid without duplicating code
我正在尝试创建一个公司 class 并且到目前为止已经编写了以下代码:
class Company:
def __init__(self, name, stocks_num, stock_price, comp_type):
self.name = name
self.stocks_num = stocks_num
self.stock_price = stock_price
self.comp_type = comp_type
if not self.valid(name,stocks_num, stock_price, comp_type):
raise ValueError("wrong Company Input")
def valid(self,name,stocks_num,stock_price,comp_type):
valid = True
check_list = [name, comp_type]
while check_list:
if ' ' in check_list[0] or not isinstance(check_list[0], str) or not check_list[0].replace(' ','').isalpha() or not check_list[0][0].isupper() \
or not len(check_list[0]) > 2:
valid = False
check_list.pop(0)
if not isinstance(stocks_num, int) or not stocks_num > 0:
valid = False
if not isinstance(stock_price, int) and not isinstance(stock_price, float) or not stock_price > 0:
valid = False
return valid
如您所见,我有这种适合我的验证过程,问题是我想创建更改实例名称、库存编号等的函数'
我希望这些函数输入具有与原始实例输入相同的验证过程。
例如:
def set_name(self, name):
# change company name
*checks if only the name is valid*
self.name = valid_new_name
有什么方法可以不从 __init__
复制相同的代码吗?或者必须输入所有 valid()
个参数而不是我想要的那个?
您可以将验证检查抽象为它自己的函数,并在整个 class 中调用它。也可以在构造函数中使用,在对象初始化时自动调用
如果您要使用 setter 来检查字段的有效性,那么您只需让构造函数调用 setter。您的所有字段都独立于其他字段,因此您真的不需要主要的有效性检查功能。
class Company:
def __init__(self, name, stocks_num, stock_price, comp_type):
self.set_name(name)
self.set_stocks_num(stocks_num)
self.set_stock_price(stock_price)
self.set_comp_type(comp_type)
def set_name(self, name):
if not is_valid_name(name):
raise ValueError("bad name")
self.name = name
def set_stocks_num(self, stocks_num):
if not isinstance(stocks_num, int) or not stocks_num > 0:
raise ValueError("bad stocks_num")
self.stocks_num = stocks_num
def set_stock_price(self, stock_price):
if not isinstance(stock_price, int) and not isinstance(stock_price, float) or not stock_price > 0:
raise ValueError("bad stock_price")
self.stock_price = stock_price
def set_comp_type(self, comp_type):
if not is_valid_name(comp_type):
raise ValueError("bad comp_type")
self.comp_type = comp_type
def is_valid_name(name):
return (
' ' not in name and
isinstance(name, str) and
name.replace(' ','').isalpha() and
name[0].isupper() and
len(name) > 2
)
请注意,所有这些 isinstance
检查都不是真正的 Pythonic。当您强制执行严格类型时,您会阻止调用者使用 duck typing 来传递可以工作但您没有预料到的类型。我会删除它们。
说到 Pythonic,setter 也不是很流行。您可以将它们切换为 properties,以便用户可以使用 =
.
分配给字段
我正在尝试创建一个公司 class 并且到目前为止已经编写了以下代码:
class Company:
def __init__(self, name, stocks_num, stock_price, comp_type):
self.name = name
self.stocks_num = stocks_num
self.stock_price = stock_price
self.comp_type = comp_type
if not self.valid(name,stocks_num, stock_price, comp_type):
raise ValueError("wrong Company Input")
def valid(self,name,stocks_num,stock_price,comp_type):
valid = True
check_list = [name, comp_type]
while check_list:
if ' ' in check_list[0] or not isinstance(check_list[0], str) or not check_list[0].replace(' ','').isalpha() or not check_list[0][0].isupper() \
or not len(check_list[0]) > 2:
valid = False
check_list.pop(0)
if not isinstance(stocks_num, int) or not stocks_num > 0:
valid = False
if not isinstance(stock_price, int) and not isinstance(stock_price, float) or not stock_price > 0:
valid = False
return valid
如您所见,我有这种适合我的验证过程,问题是我想创建更改实例名称、库存编号等的函数' 我希望这些函数输入具有与原始实例输入相同的验证过程。
例如:
def set_name(self, name):
# change company name
*checks if only the name is valid*
self.name = valid_new_name
有什么方法可以不从 __init__
复制相同的代码吗?或者必须输入所有 valid()
个参数而不是我想要的那个?
您可以将验证检查抽象为它自己的函数,并在整个 class 中调用它。也可以在构造函数中使用,在对象初始化时自动调用
如果您要使用 setter 来检查字段的有效性,那么您只需让构造函数调用 setter。您的所有字段都独立于其他字段,因此您真的不需要主要的有效性检查功能。
class Company:
def __init__(self, name, stocks_num, stock_price, comp_type):
self.set_name(name)
self.set_stocks_num(stocks_num)
self.set_stock_price(stock_price)
self.set_comp_type(comp_type)
def set_name(self, name):
if not is_valid_name(name):
raise ValueError("bad name")
self.name = name
def set_stocks_num(self, stocks_num):
if not isinstance(stocks_num, int) or not stocks_num > 0:
raise ValueError("bad stocks_num")
self.stocks_num = stocks_num
def set_stock_price(self, stock_price):
if not isinstance(stock_price, int) and not isinstance(stock_price, float) or not stock_price > 0:
raise ValueError("bad stock_price")
self.stock_price = stock_price
def set_comp_type(self, comp_type):
if not is_valid_name(comp_type):
raise ValueError("bad comp_type")
self.comp_type = comp_type
def is_valid_name(name):
return (
' ' not in name and
isinstance(name, str) and
name.replace(' ','').isalpha() and
name[0].isupper() and
len(name) > 2
)
请注意,所有这些 isinstance
检查都不是真正的 Pythonic。当您强制执行严格类型时,您会阻止调用者使用 duck typing 来传递可以工作但您没有预料到的类型。我会删除它们。
说到 Pythonic,setter 也不是很流行。您可以将它们切换为 properties,以便用户可以使用 =
.