【python3的学习之路十一】面向对象编程

  • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
  • 方法: 类中定义的函数。
  • 类变量: 类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
  • 数据成员: 类变量或者实例变量用于处理类及其实例对象的相关的数据。
  • 方法重写: 如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
  • 实例变量: 定义在方法中的变量,只作用于当前实例的类。
  • 继承: 即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟"是一个(is-a)"关系(例图,Dog是一个Animal)。
  • 实例化: 创建一个类的实例,类的具体对象。
  • 对象: 通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

类和实例

class Student(object):
      pass

class后面紧接着类名,即Student,类名通常是大写开头的单词,紧接着是(object),表示该类是从哪个类继承下来的。如果没有适合的继承类,就使用object类,这是所有类最终都会继承的类。

class Student(object):  
      def __init__(self, name, score):
          self.name = name
          self.score = score

我们可以通过定义一个特殊的__init__方法(构造方法),在创建实例的时候,把我们一些认为必须绑定的属性强制填写进去。
在__init__方法的第一个参数永远是self,便是创建的实例本身,因此,在__init__方法内部,就可以把各种属性绑定到self,因为self就指向创建的实例本身。self代表类的实例,而非类

数据封装

如果Student本身就存在一些数据,我们就没有必要从外面的函数去访问,可以直接在Student类的内部定义访问数据的函数,这样,就把“数据”给封装起来了。这些封装数据的函数是和Student类本身是关联起来的,我们称之为类的方法

class Student(object):
    def __init__(self, name, score):
        self.name = name
        self.score = score

    def get_grade(self):
        if self.score >= 90:
            return 'A'
        elif self.score >= 60:
            return 'B'
        else:
            return 'C'

访问限制

类的私有属性
__private_attrs:两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。

类的方法
在类地内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self,且为第一个参数,self 代表的是类的实例。
self 的名字并不是规定死的,也可以使用 this,但是最好还是按照约定是用 self。

类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,只能在类的内部调用 ,不能在类地外部调用。self.__private_methods。

class Student(object):
      def __init__(self, name, score):
          self.__name = name
          self.__score = score
     
      def print_score(self):
          print("%s:%s" % (__name, __score))
   
      def get_name(self):
          return self.__name     # 获取name

      def get_score(self):
          return self.__score    # 获取score

      def set_score(self, score):
          self.__score = score   # 允许外部代码修改score

类的专有方法:

__init__ : 构造函数,在生成对象时调用
__del__ : 析构函数,释放对象时使用
__repr__ : 打印,转换
__setitem__ : 按照索引赋值
__getitem__: 按照索引获取值
__len__: 获得长度
__cmp__: 比较运算
__call__: 函数调用
__add__: 加运算
__sub__: 减运算
__mul__: 乘运算
__div__: 除运算
__mod__: 求余运算
__pow__: 乘方

继承

class Animal(object):
      def run(self):
          print('Animal is running...')

class Dog(Animal):
      pass

class Cat(Animal):
      pass

print(Dog().run())    # Animal is running...
print(Cat().run())    # Animal is running...

多态

class Animal(object):
      def run(self):
          print('Animal is running...')

class Dog(Animal):
      def run(self):
          print('Dog is running...')

class Cat(Animal):
      def run(self):
          print('Cat is running...')

print(Dog().run())    # Dog is running...
print(Cat().run())    # Cat is running...

获取对象信息

  • type()

我们可以使用type()函数判断基本类型,如果一个变量指向函数或者类,也可以用type()判断。

>>> type(123)
<class 'int'>
>>> type('str')
<class 'str'>
>>> type(None)
<type(None) 'NoneType'>
>>> type(123)==type(456)
True
>>> type(123)==int
True
>>> type('abc')==type('123')
True
>>> type('abc')==str
True
>>> type('abc')==type(123)
False
  • isinstance()

对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。

>>> a = Animal()
>>> d = Dog()
>>> h = Husky()
>>> isinstance(h, Husky)
True
>>> isinstance(h, Dog)
True
>>> isinstance(h, Animal)
True
>>> isinstance(d, Dog) and isinstance(d, Animal)
True
>>> isinstance(d, Husky)
False

并且还可以判断一个变量是否是某些类型中的一种,比如下面的代码就可以判断是否是list或者tuple

>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))
True
  • dir()

如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list。

>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']

实例属性和类属性

class Student(object):
      name = 'Student'

>>> s = Student() # 创建实例s
>>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性
Student
>>> print(Student.name) # 打印类的name属性
Student
>>> s.name = 'Michael' # 给实例绑定name属性
>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
Michael
>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问
Student
>>> del s.name # 如果删除实例的name属性
>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
Student
原文地址:https://www.cnblogs.com/CSgarcia/p/9706367.html