我有一个数据模型,它具有一些原始和数组类型属性,如下所示:
class WordCollection:
"""First model"""
def __init__(self, **properties):
self.name = ""
self.status = CommonStatus.active
self.expire_time = time.time() + 1000 * 60 * 24 # after 1 day
self.created_date = time.time()
self.words = []
self.__dict__.update(properties)
这是一些黑客攻击。例如,当我使用不属于类的属性构造类时,它很容易被黑客攻击。
collection = WordCollection(**{..., "hack_property":"large text or irrelative data"})
所以我在课堂初始化方法上玩了:
class WordCollection:
"""Second model"""
def __init__(self, **properties):
self.name = properties["name"] if "name" in properties else ""
self.status = properties["active"] if "active" in properties else CommonStatus.active
self.expire_time = properties["expire_time"] if "expire_time" in properties else time.time() + 1000 * 60 * 24 # after 1 day
self.created_date = properties["created_date"] if "created_date" in properties else time.time()
self.words = properties["words"] if "words" in properties else []
但是上面的代码并没有完全解决问题:
collection = WordCollection(**{..., "name":{"hack_property":"large text or irrelative data"}})
这是最后一次重建的代码:
class WordCollection:
"""Third Model"""
def __init__(self, **properties):
self.name = properties["name"] if "name" in properties and isinstance(properties["name"], str) else ""
self.status = properties["active"] if "active" in properties \
and isinstance(properties["status"], int) else CommonStatus.active
....
以上版本解决了我的问题,但它带来了条件复杂性,我相信这将是比上述更好的解决方案。
答案 0 :(得分:0)
更标准的配方:
valid_properties = {'prop1', 'prop2', 'prop3'}
class WordCollection(object):
def __init__(self, name="", status=None; **properties):
# This one is explicit, with a default that is specified in the call signature
# Defaults in the call signature are resolved when the class is imported
self.name = name
# This one is more dynamic - CommonStatus.active could change
# after the user imports the class, so we don't want it fixed.
# Instead, use a sentinel.
# I usually use None. If None is a valid value, best bet
# is to do something like this:
# sentinel = object()
# then use that instead of None.
self.status = CommonStatus.active if status is None else status
# This one we just assign -
self.words = []
# You don't _have_ to include a **kwargs if you don't want to.
# If you don't want _any_ surprise properties, just leave
# **properties out of the __init__, and only ones you explicit
# declare will be allowed.
# Explicit is better - they show up in tab completion/help
# But if you want to filter out input to a set of valid props...
filtered_props = {k:v for k,v in properties.items() if k in valid_properties}
self.__dict__.update(filtered_props)