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

liftword3个月前 (03-17)技术文章14

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

Python命令行参数解析模块argparse

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

python函数参数详解

python有两种传参的方式,位置参数和关键字参数位置参数位置参数是基于它们的位置或顺序传递给函数的参数。这些参数是必需的,并且必须按照与函数参数列表匹配的正确顺序提供。以下是一个示例:def gre...

如何在运行 Python 脚本文件时传递参数

在 Python 中,可以使用命令行参数为程序传递额外的信息。在操作系统的命令行运行 Python 脚本文件时,文件名称之后添加的参数称为命令行参数。可以根据需要使用这些命令行参数,比如根据不同的参数...

Python教程(25)——Python中参数类型详解

当我们在编写函数时,会定义一些占位符,这些占位符就是参数,参数是函数定义中用于接收外部传递值的占位符,这个会帮助我们在函数被调用时接收外部传递的值。在Python当中,有各种各样类型的参数,主要有位置...

python unittest框架参数化学习

参数化有些测试用例会考虑正向、逆向、边界、极端等情况,一个测试方法上会有多种不同的参数,使用参数化可以实现参数数据和脚本分离,可以管理大量参数数据,循环执行测试用例,提高代码复用率。unittest框...