Setters Getters Properties

为了数据封装,有时你希望拥有一个属性,该属性值来自其他属性,或者通常,此时应计算哪个值。处理这种情况的标准方法是创建一个名为 getter 或 setter 的方法。

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

在上面的例子中,如果我们创建一个包含标题和作者的新书,很容易看出会发生什么。如果我们要添加到图书馆的所有图书都有作者和标题,那么我们可以跳过 getter 和 setter 并使用点符号。但是,假设我们有一些没有作者的书籍,我们想将作者设置为未知。或者,如果他们有多位作者,我们计划返回一份作者列表。

在这种情况下,我们可以为 author 属性创建一个 getter 和 setter。

class P:
    def __init__(self,title,author):
        self.title = title
        self.setAuthor(author)

    def get_author(self):
        return self.author

    def set_author(self, author):
        if not author: 
            self.author = "Unknown"
        else:
            self.author = author

不建议使用此方案。

一个原因是有一个问题:我们假设我们已经使用 public 属性设计了我们的类,没有方法。人们已经使用了很多,他们编写了这样的代码:

>>> book = Book(title="Ancient Manuscript", author="Some Guy")
>>> book.author = ""  #Cos Some Guy didn't write this one!

现在我们遇到了问题。因为作者不是属性! Python 提供了一个称为属性的问题的解决方案。获取属性的方法在其标题之前使用 @property 进行修饰。我们想要用作 setter 的方法在它之前用 @ attributeName.setter 进行修饰。

记住这一点,我们现在有了新的更新类。

class Book:
    def __init__(self, title, author):
        self.title = title
        self.author = author

    @property
    def author(self):
        return self.__author

    @author.setter
    def author(self, author):
        if not author: 
            self.author = "Unknown"
        else:
            self.author = author

请注意,通常 Python 不允许你使用具有相同名称和不同数量参数的多个方法。但是,在这种情况下,Python 允许这样做,因为使用了装饰器。

如果我们测试代码:

>>> book = Book(title="Ancient Manuscript", author="Some Guy")
>>> book.author = ""  #Cos Some Guy didn't write this one!
>>> book.author 
Unknown