类的命名规范
- 类中受保护的实例属性,应该以一个下划线开头。
- 类中私有的实例属性,应该以两个下划线开头。
- 类和异常的命名,应该每个单词首字母大写。
- 模块级别的常量,应该采用全大写字母,如果有多个单词就用下划线进行连接。
- 类的实例方法,应该把第一个参数命名为 self 以表示对象自身。
- 类的类方法,应该把第一个参数命名为 cls 以表示该类自身。
一点说明
python 的类中,属性(成员)和方法(成员函数)的访问权限只有两种,公开和私有。在 python 中,没有类似于 c++ 中的 privite 的修饰权限词,如果想让某属性或方法是私有的,需要在命名时以两个下划线开头。私有属性体现的是类的封装特性。
不过其实 python 的私有属性或方法在类外也是可以访问的,使用下划线 + 类名 + 私有方法(test._Test__bar())即可。但实际上,设置私有属性或方法会导致子类无法方便地访问该属性和方法,因此不建议那么设置。
在 c++ 中,有 protected 修饰权限词,方便子类访问相应的属性和方法,protecte 体现了类的继承特性。在 python 中,命名时统一建议将需要保护的属性或方法,以单下划线开头。这样做实际上没有限制作用,意在提醒该属性或方法是受保护的,在本类之外的访问需保持谨慎。此外,也可以通过设置属性的 getter 和 setter 来限制外界的访问,并且可以方便地做输入检查。
1 # -*- coding: utf-8 -*- 2 """ 3 @author: kurrrr 4 """ 5 6 7 class Player(object): 8 9 def __init__(self, name, age): 10 self._name = name 11 self._age = age 12 13 def __str__(self): 14 return '%s: %d' % (self._name, self._age) 15 16 17 def main(): 18 player = Player('Novak', 18) 19 print(player) 20 player._age = -32 21 print(player) 22 23 if __name__ == '__main__': 24 main()
- 注意到,虽然暗示是受保护地属性,但是在类外依然可以访问,且可以随意设置值,不方便做输入检查。
- 第一种方法是将 age 属性设置为 私有属性,即 __age,同时增加函数进行 age 值的设置,这样避免了外界访问,但也会带来继承类不能访问的问题,并且增加函数会给类操作带来麻烦。
- 第二种方法是使用 @property 装饰器。
1 # -*- coding: utf-8 -*- 2 """ 3 @author: kurrrr 4 """ 5 6 7 class Player(object): 8 9 def __init__(self, name, age): 10 self._name = name 11 self._age = age 12 13 @property 14 def name(self): 15 return self._name 16 17 @property 18 def age(self): 19 return self._name 20 21 @age.setter 22 def age(self, age): 23 self._age = age 24 25 def __str__(self): 26 return '%s: %d' % (self._name, self._age) 27 28 29 def main(): 30 player = Player('Novak', 18) 31 print(player) # using __str__() 32 print(player._name) # 类外访问受保护的属性,不建议的操作 33 print(player.name) # 调用name()方法 34 player.age = 34 35 print(player) # 调用age()方法 36 37 38 if __name__ == '__main__': 39 main()
- 第 10、11 行,_name 和 _age 暗示它们是类的受保护的属性。
- 第 13 ~ 15 行,通过 @property 装饰器使得在类外可以通过 对象.属性 得到对应的属性值,见第 33 行的调用。同时 @property 装饰器还自动创建了 @name.setter 装饰器,该程序中没有使用。
- 第 17 ~ 23 行,通过 @property 和 @age.setter 装饰器使得可以在类外使用 对象.属性 得到对应的属性值,对象.属性 = 新属性值 进行赋值。如果需要做赋值检查,可以在 age(self, age) 函数中实现,这里不做介绍。
python 类中几种特殊的方法
- __init__(self),初始化方法,定义对象时调用。
- __call__(self)
- __str__(self),print(obj) 时调用。
- __int__(self)
- __add__(self)
- __sub__(self)
- __mul__(self)
- __div__(self)
- __del__(self),del obj 时调用。
类的成员与对象的成员
1 # -*- coding: utf-8 -*- 2 """ 3 @author: kurrrr 4 """ 5 6 class Player: 7 _gender = 'male' 8 9 def __init__(self, name, age): 10 self._name = name 11 self._age = age 12 13 def __str__(self): 14 return '%s %s %d' % (self._name, self._gender, self._age) 15 16 def main(): 17 player = Player('Novak', 33) 18 print(player) 19 20 if __name__ == '__main__': 21 main()
- 这里的 _gender 就是属于类的属性,它会自动包含在类的成员中,可以在类中调用。
类的继承与多态
待更新...
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现