zoukankan      html  css  js  c++  java
  • python基础 类

    类的命名规范


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

    类的继承与多态


    待更新...

  • 相关阅读:
    POJ 3261 Milk Patterns (求可重叠的k次最长重复子串)
    UVaLive 5031 Graph and Queries (Treap)
    Uva 11996 Jewel Magic (Splay)
    HYSBZ
    POJ 3580 SuperMemo (Splay 区间更新、翻转、循环右移,插入,删除,查询)
    HDU 1890 Robotic Sort (Splay 区间翻转)
    【转】ACM中java的使用
    HDU 4267 A Simple Problem with Integers (树状数组)
    POJ 1195 Mobile phones (二维树状数组)
    HDU 4417 Super Mario (树状数组/线段树)
  • 原文地址:https://www.cnblogs.com/kurrrr/p/13160698.html
Copyright © 2011-2022 走看看