python - 使用属性装饰器时类属性不更新
问题描述
我正在尝试使用属性装饰器来验证 python 对象。
以下是我的课
'''Contains all model classes. Each class corresponds to a database table'''
from validation import company_legal_type, max_len
class Company():
'''A class to represent a company and its basic information'''
def __init__(self, ref, name, currency, legal_type, business):
self._ref = int(ref)
self._name = name
self._currency = str(currency) # i.e. The functional currency
self._legal_type = str(legal_type)
self._business = str(business)
def __str__(self):
return f"Company object for '{self._name}'"
# Validate object attributes
@property # Prevents change to ref after company object has been created
def ref(self):
return self._ref
@property # The following two functions permit changes but set validation checks for name
def name(self):
return self._name
@name.setter
def name(self, value):
if type(value) != str:
raise TypeError("Company name must be a string.")
if len(value) > max_len['company_name']:
raise ValueError(f"Company name must not be longer than {str(max_len['company_name'])} characters.")
以下是validation.py
# data length validation
max_len = {
'company_name': 200,
'company_business': 200,
}
最后是我如何使用这个类:
# Import custom modules
from models import Company, Currency
company = Company(23, 'ABC Limited', 'PKR', 'pvt_ltd', 'manufacturing')
company.name = 'ABCD Limited'
print(company.name)
这将打印“ABC Limited”而不是“ABCD Limited”。
如果我在更新 company.name 时破坏了验证条件,例如使用整数而不是字符串,则会正确导致错误。但是如果我在创建对象时破坏它,则不会引发错误。
我究竟做错了什么?
解决方案
问题是你的二传手没有设置任何东西。它只会在输入错误时引发错误。所以你必须实际设置一些东西,否则你希望它如何修改self._name
?所以:
@name.setter
def name(self, value):
if type(value) != str:
raise TypeError("Company name must be a string.")
if len(value) > max_len['company_name']:
raise ValueError(f"Company name must not be longer than {str(max_len['company_name'])} characters.")
self._name = value
如果我在更新 company.name 时破坏了验证条件,例如使用整数而不是字符串,则会正确导致错误。但是如果我在创建对象时破坏它,则不会引发错误。
因为您不使用__init__
. 通常,如果您有验证属性设置器,您希望使用__init__
. 所以你__init__
应该是这样的:
def __init__(self, ref, name, currency, legal_type, business):
self._ref = int(ref)
self.name = name
self._currency = str(currency) # i.e. The functional currency
self._legal_type = str(legal_type)
self._business = str(business)