关于python:类中参数的条件或限制?

Conditions or restrictions for arguments in a class?

在类中实现参数条件项的一些方法是什么?

下面是我的一个例子,以下面的课程为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Person(object):
    def __init__(self, name, gender, age):

        self.name = name
        self.gender = gender
        self.age = age

    def get_name(self):
        return self.name

    def get_gender(self):
        return self.gender

    def get_age(self):
        return self.age

在上述情况下,我只希望在名称、性别和年龄的参数分别为strstrint类型的情况下,从个人类创建一个对象。

换句话说,如果我键入:

1
bill = person('Bill McFoo', 'Male', '20')

不会创建对象bill,因为年龄是字符串而不是整数。

这是我的方法;我在__init__方法中包括一个if语句:

1
2
3
4
5
6
7
8
9
10
11
def __init__(self, name, gender, age):

    self.name = name

    if isinstance(age, str):
        print("Age needs to be an integer you f**king idiot!")
        raise ValueError
    else:
        self.age = age

    self.gender = gender

所以在上面的例子中,参数age的输入被检查为一个整数,如果不是,那么它会责备用户并引发一个异常,从而阻止创建对象。我可以对namegender做同样的操作,并检查它们是否与isinstance有关联。

所以我想知道是否有更简单或"正确"的方法来实现类的参数检查,而不是我所做的方法?


So I'm wondering if there are simpler or 'right' ways to implement
argument checks like this for a class instead of the approach that
I've done?

正确的方法是什么都不要检查。在Python中,假设当您询问对象时,对象知道要做什么,然后在出现问题时捕获异常。

如果必须这样做,则尝试将对象转换为预期的类型,然后捕获异常:

1
2
3
4
5
try:
   age = int(age)
except ValueError:
   # do something
   raise

或者很简单地说,如果你只是想重新提出例外——你不需要抓住它:

1
self.age = int(age)

现在,如果age不是可以转换为整数的东西,并且您没有异常处理程序,那么python将引发异常——默认的异常处理程序将捕获异常并停止程序的执行。

这种模式称为EAFP:

EAFP

Easier to ask for forgiveness than permission. This common Python
coding style assumes the existence of valid keys or attributes and
catches exceptions if the assumption proves false. This clean and fast
style is characterized by the presence of many try and except
statements. The technique contrasts with the LBYL style common to many
other languages such as C.

另外,在Python中不需要"getter/setter"方法。因此,您可以摆脱get_name等,直接访问属性。


Python是鸭子型的。这意味着,您不必检查对象是否为Duck类型,而只需检查它是否具有quack()walk()功能(这个duck示例是名称的来源)。当我看到一只鸟像鸭子一样走路,像鸭子一样游泳,像鸭子一样嘎嘎叫时,我把它叫做鸭子。

如果您真的需要检查传递的参数是否为int类型,请像您那样使用isinstance,但请注意,这被认为是不好的做法,因为它会破坏python被duck类型化的整点。