Python定义Dataclass与抽象类时出现<bound method>提示的含义及正确实现方式咨询
解释
<bound method...>提示信息&修复代码问题 一、先搞懂你看到的那条提示信息
你打印handler.class_name时出现的<bound method my_class_handler.class_name of <__main__.my_class_handler object at 0x000001A55FB96580>>,意思很直白:
- 你没有给
class_name加括号(),所以Python没有调用这个方法,而是直接返回了这个方法本身的「绑定实例」——也就是说,这个方法已经和handler这个具体对象绑定在一起了,打印出来的就是它的内存状态描述。 - 当然这只是表面现象,你的代码还有更深层的设计问题需要调整。
二、你的代码里的核心问题
1. 抽象类的方法重载错误
Python不支持像Java那样的同名方法重载(仅靠参数不同定义多个同名方法),所以你在iclass_handler里定义的两个class_name抽象方法,后面的会直接覆盖前面的,相当于只定义了带参数的那个抽象方法,无参的版本等于白写。
2. 子类的方法覆盖&拼写错误
- 你在
my_class_handler里定义的两个class_name方法也是同理,带参数的方法直接覆盖了无参的,所以你调用handler.class_name()的时候会直接报错(因为它只认带参数的版本)。 - 无参的
class_name方法里写的是return self.obj.class_names,这里多了个s,应该是self.obj.class_name,运行时会触发AttributeError。
3. Dataclass的类型不匹配
你初始化my_class时给columns传了None,但类型标注是List[column],None不符合列表类型要求,应该传空列表[]。
三、正确的实现方向:用@property实现属性读写
在Python里,如果你想给类实现「可读可写的属性」,同时遵循抽象类的约束,最优雅的方式是用@property装饰器。下面是修改后的完整代码:
from abc import ABC, abstractmethod from dataclasses import dataclass from typing import List @dataclass class Column: # 类名遵循PEP8大驼峰命名规范 name: str heading: str @dataclass class MyClass: class_name: str class_description: str columns: List[Column] class IClassHandler(ABC): @property @abstractmethod def class_name(self) -> str: pass @class_name.setter @abstractmethod def class_name(self, value: str) -> None: pass class MyClassHandler(IClassHandler): def __init__(self): # 给columns传空列表,符合List[Column]的类型要求 self.obj = MyClass("test-class", "", []) @property def class_name(self) -> str: return self.obj.class_name # 修正拼写错误 @class_name.setter def class_name(self, value: str) -> None: if value != self.obj.class_name: self.obj.class_name = value if __name__ == '__main__': handler = MyClassHandler() print(handler.class_name) # 直接访问属性,不用加括号,输出"test-class" handler.class_name = "new-test-class" print(handler.class_name) # 输出"new-test-class"
改动说明:
- 命名规范:把类名改成Python推荐的大驼峰格式,提升代码可读性。
- 抽象类定义:用
@property和@class_name.setter定义抽象的可读可写属性,替代原来的重载方法,符合Python抽象类的设计逻辑。 - 子类实现:用
@property实现getter,@class_name.setter实现setter,这样你就可以像访问普通属性一样用handler.class_name获取值,用handler.class_name = "xxx"设置值,再也不会出现<bound method...>的提示。 - 修复类型错误:初始化
MyClass时给columns传空列表,符合类型标注要求。
补充学习方向
如果想深入了解这部分内容,可以重点学习:
- Python的
@property装饰器用法(实现属性封装) - Python抽象基类(ABC)的正确使用方式
- PEP8命名规范
- Dataclass的类型标注与初始化注意事项
内容的提问来源于stack exchange,提问作者jump
相关产品推荐
相关产品推荐

