yann-qu

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  30 随笔 :: 0 文章 :: 2 评论 :: 36915 阅读

记录一次python编程中遇见的错误,加深对类和对象、属性和方法的理解

注意: python是动态语言,属性和方法可以随时添加与修改。且python没有重载,重写函数会导致函数的覆盖。使用装饰器后可以吧方法装饰成属性,此时可以创建同名的不同方法,但是这些方法的装饰器必须有差异

class Person():
def __init__(self, name, age):
self._name = name
self._age = age
# @property
def name(self):
return self._name
# @property
def age(self):
return self._age
# @age.setter
def age(self, value):
# 由于没使用装饰器。该方法会将age(self)方法覆盖
self._age = value
person = Person('yann', 12)
# print(person.age()) # ERROR,因为age(self)方法已经被覆盖
person.age(18) # 调用了age(self, value)方法,将年龄设置为18
print(person.age) # 输出person对象age()方法的地址
person.newage = 18 # person对象本来没有age属性(__init__方法只初始化了_name和_age属性),本操作为person对象添加了一个名字为newage的属性
person.age = 18 # 此操作修改了person的age属性,本身该属性指向了一个函数的地址,此操作将其值修改为18
# person.age(10) # ERROR,'int' object is not callable。age属性已经被修改成18了,导致age(self, value)方法不能再被调用。该错误反映出不能有同名的属性和方法,否则会发生覆盖,无法正常使用。

显然,这种可以随时添加对象所拥有的属性的操作可能带来风险。如果我们需要限定自定义类型的对象只能绑定某些属性,可以通过在类中定义__slots__变量来进行限定。需要注意的是__slots__的限定只对当前类的对象生效,对子类并不起任何作用。

例子:

class Person():
__slots__ = ('_name', '_age')
def __init__(self, name, age):
self._name = name
self._age = age
def add_property(self, pro):
self._pro = pro
@property
def name(self):
return self._name
@property
def age(self):
return self._age
@age.setter
def age(self, value):
self._age = value
def main():
person = Person('yann', 12)
person.age = 18
# person._name = 'qu' # 也可以直接访问该属性。毕竟不是真正的私有
person.add_property(123) # ERROR,'Person' object has no attribute '_pro'
posted on   yann-qu  阅读(30)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示