八千里路云和月

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

类的命名规范


  • 类中受保护的实例属性,应该以一个下划线开头。
  • 类中私有的实例属性,应该以两个下划线开头。
  • 类和异常的命名,应该每个单词首字母大写。
  • 模块级别的常量,应该采用全大写字母,如果有多个单词就用下划线进行连接。
  • 类的实例方法,应该把第一个参数命名为 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 就是属于类的属性,它会自动包含在类的成员中,可以在类中调用。 

 

类的继承与多态


 

待更新...

 

posted on   hanX3  阅读(183)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示