python散装笔记——144: 属性访问

liftword2个月前 (03-17)技术文章7

1: 使用点符号进行基本属性访问

我们先来看一个示例类。

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

book1 = Book(title="Right Ho, Jeeves", author="P.G. Wodehouse")

在Python中,你可以使用点符号访问类的属性title

>>> book1.title
'P.G. Wodehouse'

如果属性不存在,Python会抛出一个错误:

>>> book1.series
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'Book' object has no attribute 'series'

2: 设置器、获取器和属性

为了实现数据封装,有时你希望有一个属性,其值来自其他属性,或者其值需要在那一刻计算得出。处理这种情况的标准方法是创建一个方法,称为获取器(getter)或设置器(setter)。

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

在上面的例子中,很容易看出,如果我们创建一本包含标题和作者的新书,会发生什么。如果我们要添加到图书馆的所有书籍都有作者和标题,那么我们可以跳过获取器和设置器,直接使用点符号。然而,假设我们有一些书籍没有作者,我们希望将作者设置为“Unknown”。或者如果它们有多个作者,我们计划返回一个作者列表。

在这种情况下,我们可以为author属性创建一个获取器和一个设置器。

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

  def getAuthor(self):
    return self.author
  
  def setAuthor(self, author):
    if not author:
      self.author = "Unknown"
    else:
      self.author = author

这种方案不推荐。

原因之一是存在一个陷阱:假设我们设计类时使用了公共属性,而没有方法。人们已经大量使用了它,并且他们编写了如下代码:

>>> book = Book(title="Ancient Manuscript", author="Some Guy")
>>> book.author = "" # 这将覆盖掉作者 Some Guy!

现在我们遇到了问题。因为author不是一个属性!Python提供了一个名为属性(properties)的解决方案来解决这个问题。通过在方法头部之前使用@property装饰器来获取属性。我们希望作为设置器的方法在之前使用@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

属性封装

  • 使用@property装饰器可以将方法伪装成属性,从而在访问属性时执行特定的逻辑。
  • 使用@attributeName.setter装饰器可以定义设置属性时的行为。

私有属性

  • Book类中,__author是一个私有属性,只能通过author属性访问和修改。这有助于封装数据,防止直接访问内部实现。

默认值处理

  • 在设置器中,如果传入的author为空,则自动设置为"Unknown",这提供了一种默认值处理机制。

通过使用属性(properties),你可以更灵活地控制属性的访问和设置,同

相关文章

Python 函数参数

1.函数基本参数#基本样例 函数参数的定义要和调用参数匹配,否则会报错 def fun01(a, b): print(a, b) if __name__ == '__main__':...

Python基础 - 函数的位置参数、关键字参数、默认参数

在 Python 中,调用函数可以按照函数的位置传递参数(位置参数),也可以按照参数的名称传递参数(关键字参数),函数的参数还可以在定义的时候指定默认值(默认参数)。此外,Python 还支持可变参数...

python之函数的参数详解

参数传递:1.不可变数据类型:数字number(含int、float、bool、complex)、字符串string、元组tuple。当不可变数据类型被当作函数的参数,传递的是值,函数体内改变值时实际...

真相!Python 默认值参数深度解析,从踩坑到精通的进阶秘籍

一、开发中遇到的问题问题 1:默认值参数为可变对象的陷阱在 Python 开发里,不少初学者会在默认值参数为可变对象时踩坑。比如,我们想定义一个函数,用于向列表中添加元素,代码如下:def add_t...

Python命令行参数解析模块argparse

前言以前 optparse 比较火,但是在python2.7版本后,官方不再维护这个模块,转而大力支持 argparse 。argparse 模块可以让人轻松编写用户友好的命令行接口。她可以从 sys...

【Python程序开发系列】一文总结Python函数参数和传递方式

这是我的第217篇原创文章。一、引言函数,在定义的时候,可以有参数的,也可以没有参数。从函数定义的角度来看,参数可以分为两种:必选参数:调用函数时必须要指定的参数,在定义时没有等号可选参数:也叫默认参...