python学习(十三) python中的类

时间:2025-03-14 07:01:55

 Python使用class关键字来定义类,class关键字之后是一个空格,然后是类的名字,再然后是一个冒号,最后换行并定义类的内部实现。

 类名的首字母一般要大写,当然也可以按照自己的习惯定 义类名,但一般推荐参考惯例来命名,并在整个系统的设 计和实现中保持风格一致,这一点对于团队合作尤其重要。

class Car: 
  def infor(self):
  print(" This is a car ") 

        定义了类之后,可以用来实例化对象,并通过“对象名. 成员”的方式来访问其中的数据成员或成员方法。

>>> car = Car()
>>> ()
This is a car

 Python提供了一个关键字“pass”,类似于空语句,可以 用在类和函数的定义中或者选择结构中。当暂时没有确定 如何实现功能,或者为以后的软件升级预留空间,或者其 他类型功能时,可以使用该关键字来“占位”。

>>> class A:
pass
>>> def demo():
pass
>>> if 5>3:
pass

self参数

 类的所有实例方法都必须至少有一个名为self的参数,并 且必须是方法的第一个形参(如果有多个形参的话), self参数代表将来要创建的对象本身。

 在类的实例方法中访问实例属性时需要以self为前缀。

 在外部通过对象名调用对象方法时并不需要传递这个参数。

 如果在外部通过类名调用对象方法则需要显式为self参数 传值。

 在Python中,在类中定义实例方法时将第一个参数定义为 “self”只是一个习惯,而实际上类的实例方法中第一个参 数的名字是可以变化的,而不必须使用“self”这个名字, 尽管如此,建议编写代码时仍以self作为方法的第一个参 数名字。

>>> class A:
    def __init__(hahaha, v):
        = v
    def show(hahaha):
       print()
>>> a = A(3)
>>> ()
3

类成员与实例成员

 属于实例的数据成员一般是指在构造函数__init__()中定义 的,定义和使用时必须以self作为前缀;属于类的数据成 员是在类中所有方法之外定义的。

 在主程序中(或类的外部),实例属性属于实例(对象), 只能通过对象名访问;而类属性属于类,可以通过类名或 对象名都可以访问。

 在实例方法中可以调用该实例的其他方法,也可以访问类属性以及实例属性。

 在Python中比较特殊的是,可以动态地为类和对象增加成员,这一点是和很多面向对象程序设计语言不同的,也是 Python动态类型特点的一种重要体现。

class Car:
      price = 100000 #定义类属性
      def __init__(self, c):
           = c #定义实例属性


car1 = Car("Red") #实例化对象
car2 = Car("Blue")
print(, ) #查看实例属性和类属性的值
 = 110000 #修改类属性
 = 'QQ' #动态增加类属性
 = "Yellow" #修改实例属性
print(, , )
print(, , )
import types

def setSpeed(self, s): 
     = s

 = (setSpeed, car1) #动态增加成员方法
(50) #调用成员方法
print()
import types

class Person(object):
   def __init__(self, name):
       assert isinstance(name, str), 'name must be string'
        = name


def sing(self):
    print(+' can sing.')
def walk(self):
    print(+' can walk.')
def eat(self):
    print(+' can eat.')


>>> zhang = Person('zhang')
>>> () #用户不具有该行为
AttributeError: 'Person' object has no attribute 'sing'
>>>  = (sing, zhang)#动态增加一个新行为
>>> ()
zhang can sing.
>>> ()
AttributeError: 'Person' object has no attribute 'walk'
>>>  = (walk, zhang)
>>> ()
zhang can walk.
>>> del  #删除用户行为
>>> ()
AttributeError: 'Person' object has no attribute 'walk'

私有成员与公有成员

Python并没有对私有成员提供严格的访问保护机制

 在定义类的成员时,如果成员名以两个下划线“__”或更多下划线开头而不以两个或更多下划线结束则表示是私有成员

 私有成员在类的外部不能直接访问,需要通过调用对象的公开成员方法来访问,也可以通过Python支持的特殊方式来访问。

 公开成员既可以在类的内部进行访问,也可以在外部程序 中使用。

class A:
  def __init__(self, value1 = 0, value2 = 0):
      self._value1 = value1
      self.__value2 = value2
  def setValue(self, value1, value2):
      self._value1 = value1
      self.__value2 = value2
  def show(self):
      print(self._value1)
      print(self.__value2)

 在Python中,以下划线开头的变量名和方法名有特殊的含 义,尤其是在类的定义中。用下划线作为变量名和方法名 前缀和后缀来表示类的特殊成员:

_xxx:受保护成员,不能用'from module import *'导入;

__xxx__:系统定义的特殊成员;

__xxx:私有成员,只有类对象自己能访问,子类对象不能直接访问到这 个成员,但在对象外部可以通过“对象名._类名__xxx”这样的特殊方式来访问。

注意:Python中不存在严格意义上的私有成员。

方法

在类中定义的方法可以粗略分为四大类:公有方法、私有方法、静态方法和类方法。

       公有方法、私有方法都属于对象,私有方法的名字以两个下划线“__”开始, 每个对象都有自己的公有方法和私有方法,在这两类方法中可以访问属于类和对象的成员;

       公有方法通过对象名直接调用,私有方法不能通过对象名直接调用,只能在属于对象的方法中通过self调用或在外部通过Python支持的特殊方式来调用。

       如果通过类名来调用属于对象的公有方法,需要显式为该方法的self参数传递一个对象名,用来明确指定访问哪个对象的数据成员。

       静态方法和类方法都可以通过类名和对象名调用,但不能直接访问属于对象的成员,只能访问属于类的成员。

        静态方法可以没有参数。

        一般将cls作为类方法的第一个参数名称,但也可以使用其他的名字作为参数, 并且在调用类方法时不需要为该参数传递值。

 class Root:
   __total = 0
   def __init__(self, v): #构造方法
      self.__value = v
      Root.__total += 1

   def show(self): #普通实例方法
      print('self.__value:', self.__value)
      print('Root.__total:', Root.__total)

   @classmethod #修饰器,声明类方法
   def classShowTotal(cls): #类方法
      print(cls.__total)

   @staticmethod #修饰器,声明静态方法
   def staticShowTotal(): #静态方法
      print(Root.__total)
>>> r = Root(3)
>>> () #通过对象来调用类方法
1
>>> () #通过对象来调用静态方法
1
>>> ()
self.__value: 3
Root.__total: 1
>>> rr = Root(5)
>>> () #通过类名调用类方法
2
>>> () #通过类名调用静态方法
2

属性

 只读属性

class Test:
  def __init__(self, value):
    self.__value = value
  @property
  def value(self): #只读,无法修改和删除
    return self.__value
>>> t = Test(3)
>>> 
3
>>>  = 5 #只读属性不允许修改值
AttributeError: can't set attribute

•可读、可写属性

class Test:
  def __init__(self, value):
     self.__value = value

  def __get(self):
     return self.__value

  def __set(self, v):
     self.__value = v

  value = property(__get, __set)

  def show(self):
     print(self.__value)
>>> t = Test(3)
>>>  #允许读取属性值
3
>>>  = 5 #允许修改属性值
>>> 
5
>>> () #属性对应的私有变量也得到了相应的修改
5