如何使用Python的abc.abstractmethod定义必须重写的属性?

老宇小哥_9064

老宇小哥_9064

2026-07-20

638人浏览

原创

不能。abstractmethod 只能修饰方法,不能直接修饰属性;但自 Python 3.3 起支持 @property + @abstractmethod 组合,要求子类必须用 @property 实现同名方法,否则实例化时报错。

如何使用python的abc.abstractmethod定义必须重写的属性?

abstractmethod 能不能直接修饰属性?

不能。abstractmethod 本身只能修饰方法(函数),不能直接用在属性(@property)上——Python 解释器会报 TypeError: abstractmethod() can only be used on functions。但你可以绕过这个限制,让子类“必须实现某个属性”,关键在于把属性访问逻辑封装成一个抽象方法。

用抽象方法模拟强制属性的写法

常见做法是定义一个抽象的 getter 方法(比如 get_name),再在基类里用 @property 包一层,这样子类只需重写那个抽象方法,就能间接满足“必须提供该属性”的效果:

from abc import ABC, abstractmethod
<p>class Animal(ABC):
@property
@abstractmethod
def name(self):</p><h1>这里不能有实现,否则会触发 warning 或被忽略</h1><pre class="brush:php;toolbar:false;">    pass

✅ 正确:子类重写 @property 方法(本质是重写 getter)

class Dog(Animal): @property def name(self): return "Dog"

❌ 错误:只定义普通实例变量,不重写 property,会报 TypeError

class BadCat(Animal): def init(self): self._name = "Cat" # 这样不行,没覆盖 name 属性

注意:@property + @abstractmethod 的组合是合法的(从 Python 3.3+ 开始支持),但它要求子类也必须用 @property 实现同名方法,不能用普通字段或 setter-only 方式糊弄过去。

为什么不用 __getattr__ 或 __getattribute__ 强制检查?

有人想靠运行时拦截来“强制”属性存在,比如在 __getattr__ 里 raise NotImplementedError。这看似可行,但问题很多:

  • 它只在属性真正被访问时才报错,无法在实例化时暴露问题(违反“尽早失败”原则)
  • IDE 和类型检查器(如 mypy)完全无法识别这种契约,失去静态提示能力
  • 如果子类意外定义了同名但非 @property 的字段(比如 self.name = "xxx"),@property 会被遮蔽,且不会触发抽象检查

所以,依赖 @property + @abstractmethod 是最轻量、最符合 Python 抽象协议的方式——它让抽象检查发生在类定义阶段,而不是运行时。

python-parallelization
python-parallelization

将顺序 Python 代码转换为并行/并发实现,用于在需要并行化 Python 代码、提升性能时使用。

下载

带参数的属性怎么办?比如需要传参才能计算的“动态属性”

属性本质上不该带参数;如果需要参数,说明它其实是方法,不是属性。这时候就别硬套 @property,直接定义抽象方法更清晰:

class Shape(ABC):
    @abstractmethod
    def area(self, unit="m2"):
        pass
<p>class Circle(Shape):
def <strong>init</strong>(self, r):
self.r = r
def area(self, unit="m2"):
return 3.14 * self.r ** 2
</p>

强行把带参逻辑塞进 @property 会导致调用时写成 obj.area(unit="ft2"),这违反属性语义,也破坏 IDE 补全和文档生成逻辑。

抽象属性的边界其实很窄:它只适合那些“无参、只读、逻辑简单”的值。一旦涉及参数、状态变更或复杂计算,就该回归抽象方法——这不是妥协,是契约表达得更准确。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1731

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4384

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1709

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

25717

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3127

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3147

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1183

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2443

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程