Python之面向对象编程

Posted 桥前石头

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python之面向对象编程相关的知识,希望对你有一定的参考价值。

初识类

       类是用来描述具有相同属性和方法的对象的集合。对象是具体存在的,而类是一种抽象概念。在程序中遵循先定义类再调用类的顺序。类的名字是采用驼峰体的,类在定义阶段就会立刻执行类体内代码,将产生的名字存放在类的名称空间中,可以用__dict__查看类的名称空间,将以字典形式返回结果。

  类分为父类和子类。父类又称为基类或超类,子类又称为派生类。类有两种属性:数据属性和函数属性(函数是没有被任何装饰器装饰的)。类的数据属性是直接对象所有共享的,类的函数属性是绑定给对象用的,绑定给不同的对象就是不同的绑定方法。

class Student:
  #定义私有属性,外部无法直接访问 n
=0
#__init__()构造方法
   #self代表类的实例
   #def定义方法,类方法的第一个参数必须是用来代表类的实例的
def __init__(self,name,age,gender): self.name=name#类对象的属性引用 self.age=age self.gender=gender Student.n+=1 school=红太阳 def learn(self): return %s is learning%self.name
#obj.class指向类 stu1
=Student(aa,19,female)#类对象的实例化 # print(stu1.n) # print(stu1.learn) # #<bound method Student.learn of <__main__.Student object at 0x000001BEFD188B38>> # print(stu1.learn()) stu2=Student(bb,23,male) # print(stu2.n) # print(stu2.learn) # #<bound method Student.learn of <__main__.Student object at 0x000001BEFD188BA8>> # print(id(Student.n),Student.n) # print(id(stu1.n),stu1.n) # print(id(stu2.n),stu2.n) # #同id # Student.n=1 # print(id(Student.n),Student.n) # print(id(stu1.n),stu1.n) # print(id(stu2.n),stu2.n) #都随着Student.n变化而变 # stu1.n=1 # print(id(Student.n),Student.n) # print(id(stu1.n),stu1.n)#1345678816 1 # print(id(stu2.n),stu2.n) #只有stu1变化,其他都不变

类的实例化就是调用类产生对象的过程,实例对象就是类的实例化的结果。对象除了共有的属性和方法之外,应该还有其特有的,这样类实例化结果的对象就不是一模一样的了。要使对象就有其特征,就要在类体内定义一个__init__函数,该函数在调用类时自动触发执行。

调用类的过程将发生三件事:

  一是产生空对象;

  二是自动触发类体内的__init__函数;

  三是将空对象连同调用类时括号内的参数一起传给__init__函数。

类的使用:

  1.必须遵循函数的参数规则

  2.类中定义的函数主要是给对象使用的,而且是绑定到对象的。虽然所有对象的指向都是相同的功能,但是绑定到不同对象就是不同的绑定方法。绑定到对象的特殊之处就在于绑定谁就由谁调用,谁调用就将谁本身当做第一个参数(self)传给方法,即自动传值。

对象间的交互

class Dog:
    def __init__(self,name,d_type,aggressivity,life_value):
        self.name=name
        self.d_type=d_type
        self.aggressivity=aggressivity
        self.life_value=life_value

    def bite(self,enemy):
        enemy.life_value-=self.aggressivity
        print(‘‘‘
        狗[%s]咬人[%s]
        人掉血[%s]
        人的生命值还剩[%s]‘‘‘%(self.name,enemy.name,self.aggressivity,enemy.life_value))

dog1 = Dog(旺财, 中华田园犬, 50, 60)

class People:
    def __init__(self,name,aggressivity,life_value=100):
        self.name=name
        self.aggressivity=aggressivity
        self.life_value=life_value

    def bite(self,enemy):
        enemy.life_value -= self.aggressivity
        print(‘‘‘
                人[%s]咬狗[%s]
                狗掉血[%s]
                狗的生命值还剩[%s]‘‘‘ % (self.name, enemy.name, self.aggressivity, enemy.life_value))



people1=People(aa,30)
people1.bite(dog1)

 

继承和派生

继承就是类与类之间的关系,是创建类的一种方式,继承的 目的就是减少代码冗余。子类会遗传父类的属性,子类可以继承一个或多个父类。

寻找继承关系需要先抽象再继承。

属性查找是现从子类自己查找,找不到再去父类查找。

派生就是子类定义 自己的新属性,如果是与父类的属性同名,以子类 自己的为准。在子类派生的 新方法中重用父类功能的方式:一是指名道姓地调用,这种方式与继承关系是无关的 ,与调用普通函数是一样的;二是通过执行super()得到返回值,该返回值是一个 特殊对象,该对象专门用来调用mro()列表从当前的查找位置往后查找下一个类的属性或方法。第二种方法是严格遵循继承关系的。

 组合

1.组合是什么?

组合是用于描述一个对象拥有的属性,该属性来自于另一个类。

2.组合怎么用?

class School:
    school=‘red hair‘
    def __init__(self,name,age,gender):
        self.name=name
        self.age=age
        self.gender=gender

class Date:
    def __init__(self,year,mon,day):
        self.year = year
        self.mon = mon
        self.day = day

    def tell_birth(self):
        print(‘‘‘
        ==========
        year  [%s]
        month [%s]
        day   [%s]
        ‘‘‘%(self.year,self.mon,self.day))

class Teacher(School):
    def __init__(self,name,age,gender,level,salary):
        super(Teacher,self).__init__(name,age,gender)#用super()重用父类
        self.level=level
        self.salary=salary
        self.courses=[]

    def change_score(self):
        print(‘teacher is changing score‘)

    def tell_course_info(self):
        print((‘teacher [%s] has course:‘%self.name).center(50,‘=‘))
        for course_obj in  self.courses:
            course_obj.info()#组合

class Student(School):
    def __init__(self,name,age,gender,grade):
        super(Student,self).__init__(name,age,gender)
        self.grade=grade
        self.courses=[]

    def choose(self):
        print(‘student [%s] choose course‘%self.name)

    def tell_course_info(self):
        print((‘student [%s] learn course:‘%self.name).center(50,‘=‘))
        for course_obj in self.courses:
            course_obj.info()

class Course:
    def __init__(self,cname,period,price):
        self.cname=cname
        self.period=period
        self.price=price

    def info(self):
        print(‘‘‘
        ========course info========
        course_name     <%s>
        course_period   <%s>
        course_price    <%s>
        ‘‘‘%(self.cname,self.period,self.price))

t1=Teacher(‘aa‘,20,‘female‘,9,3.1)
# t1.birth=Date(1998,12,12)
# t1.birth.tell_birth()

s1=Student(‘bb‘,16,‘male‘,‘python‘)
# s1.birth=Date(2002,12,12)
# s1.birth.tell_birth()

python=Course(‘python‘,‘5mons‘,20000)
linux=Course(‘linux‘,‘5mons‘,20000)
go=Course(‘Go‘,‘5mons‘,25000)

# t1.course=python
# s1.course=python
# t1.course.tell_course_info()
t1.courses.append(python)
t1.courses.append(linux)
print(t1.courses)
for course_obj in t1.courses:
    course_obj.info()
# t1.tell_course_info()
s1.courses.append(go)
s1.courses.append(python)
s1.tell_course_info()

封装

1.封装是什么?

封装从字面意思上看是隐藏,但是又与隐藏有所不同,封装是对外隐藏,对内公开。

封装数据属性:把数据属性封装起来,将需要的开辟接口给外部使用者用。其好处是添加控制逻辑,从而控制访问者对属性的操作,起到隔离复杂性的效果。

2.封装如何实现隐藏?

在属性名前面加__开头,但是不是以__结尾的

class ATM:
    def __insert_card(self):
        print(‘insert your card‘)

    def __transfer(self):
        print(‘transfer‘)

    def __with_draw(self):
        print(‘withdraw‘)

    def __repay(self):
        print(‘repay‘)

    def __check_flow(self):
        print(‘check your bank flow‘)

    def run(self):
       self.__insert_card()
       self.__transfer()
       self.__with_draw()
       self.__repay()
       self.__check_flow()

obj=ATM()
obj.run()

 3.封装要注意的三个点:

    (1)为一个属性加__开头会在属性定义阶段将属性名变形,是一种语法上的变形

    (2)这种语法上变形只在定义阶段发生一次,定义之后新增的属性即使是以__开头也不会变形

    (3)如果父类不想属性被子类的覆盖就可以给该属性加__开头

多态

 1.多态是什么?

多态就是同一属性的多种形态

2.多态的特性?

可以在不考虑对象具体类型的前提下直接使用对象下的方法

3.使用多态的好处?

    (1)增加程序的灵活性

    (2)增加了程序的可扩展性

import abc  #abstractclass抽象类

class Animal(metaclass=abc.ABCMeta):#抽象基类,抽象基类本身不能再实例化
    @abc.abstractmethod
    def eat(self):
        pass

    @abc.abstractmethod
    def bark(self):
        pass

class Cat(Animal):
    def eat(self):
        print(‘cat eatting‘)

    def bark(self):
        print(‘cat bark‘)

class Dog(Animal):
    def eat(self):
        print(‘dog eatting‘)

    def bark(self):
        print(‘dog bark‘)

dog=Dog()
cat=Cat()
cat.eat()
def EAT(obj):
    obj.bark()

EAT(cat)

  

鸭子类型

  Python崇尚鸭子类型,即‘如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子’

python程序员通常根据这种行为来编写程序。例如,如果想编写现有对象的自定义版本,可以继承该对象

也可以创建一个外观和行为像,但与它无任何关系的全新对象,后者通常用于保存程序组件的松耦合度。






以上是关于Python之面向对象编程的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段9——JS中的面向对象编程

python之面向对象编程一

python基础之面向对象

Python全栈之路系列----之-----面向对象

自动化运维Python系列之面向对象

自动化运维Python系列之面向对象