在设置值和构造函数中验证值 - Python 3.3

3 投票
1 回答
1645 浏览
提问于 2025-04-18 03:25

我在Python中遇到一个设计问题,但我对这个语言、设计和异常处理都不是很熟悉。

我想要的是:我有一个类,里面有一些属性,比如名字、预算等等。我希望创建对象时,名字不能少于3个字符,预算也不能小于0。而且当我修改这些值的时候,也要重新检查。如果你试图创建一个不符合这些条件的对象,我希望能够抛出一个异常。

这是我尝试过的:

def __init__(self, name, budget):
    try:
        self.set_name(name)
        self.set_budget(budget)
    except Exception as e:
        print(e)
        return None

def set_name(name):
    if len(name) < 3:
        raise Exception("short name")
    else:
        self.__name = name

但是我遇到了两个问题 :( 第一个问题是,即使我尝试用'a'这样的名字来创建对象,它还是被创建了 :( 我不想让无效的对象被创建。第二个问题是,我在初始化方法中有打印语句,但我不想在里面使用任何输入输出的功能。那么我该如何获取消息呢?如何从构造函数中知道为什么不能创建这个对象呢?

而且,这只是一个非常简单的任务,我不想用复杂、冗长和难懂的解决方案来处理 :(

你能帮我吗?非常感谢! :)

1 个回答

2

这个任务非常简单,我不想用复杂又冗长的解决方案来搞定它。

这就是现在IT界那么多悲观情绪的原因之一,咳咳,心脏出血漏洞,不过好吧,我们还是保持简单吧 :)

你想确认的是 len(name) >= 3budget >= 0,对吧?那我们就来做吧:

class Dummy(object):
    def __init__(self, name, budget):
        self.name = name
        self.budget = budget
    @property
    def name(self):
        return self.__name
    @name.setter
    def name(self,value):
        self.validatename(value)
        self.__name = value
    @property
    def budget(self):
        return self.__budget
    @budget.setter
    def budget(self,value):
        self.validatebudget(value)
        self.__budget = value

    def validatename(self,value):
        if len(value) < 3:
            raise Exception("Some descriptive error here")
    def validatebudget(self,value):
        if isinstance(value,str):
            value = float(value) # this is more common than you'd think
        if value < 0:
            raise Exception("Some descriptive error here")

这里创建了一个函数,用来验证每个 namebudget,如果值不正确就会抛出异常(在这个类中故意不捕获,不过如果你想的话当然可以提示处理!)。这不是最好的方法,但正如你在我回答开头引用的那样,这是最简单的方法。它还利用了Python的属性(这里有相关的SO问题),定义了自定义函数来处理获取和设置 namebudget。我们来运行一个例子:

>>> testobj = Dummy("Adam",100000)
# no error
>>> testobj.name
"Adam"
>>> testobj.budget
100000
>>> testobj.name = "Brian"
>>> testobj.name
"Brian"
>>> testobj.name = "Ed"
Traceback (most recent call last):
  File "<pyshell#40>", line 1, in <module>
    testobj.name = "Ed"
  File "<pyshell#34>", line 12, in name
    self.validatename(value)
  File "<pyshell#34>", line 24, in validatename
    raise Exception("Some descriptive error here")
Exception: Some descriptive error here

撰写回答