python学习8_1 面向对象(继承多态封装)以及零散概念(组合,property,绑定方法与非绑定方法,反射,内置函数)

Posted cooky

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python学习8_1 面向对象(继承多态封装)以及零散概念(组合,property,绑定方法与非绑定方法,反射,内置函数)相关的知识,希望对你有一定的参考价值。

继承
python中的继承注意两点:
1.在Python中支持一个子类同时继承多个父类
2.python中类分两种:
新式类:继承了Object
经典类:没有继承Object
作用:
1.减少代码冗余,解决的是类与类之间的代码冗余关系

示例:可以通过__bases__属性查看继承关系
class Parent1:
    pass

class Parent2:
    pass

class SubClass(Parent1,Parent2):
    pass

print(Parent1.__bases__)
print(SubClass.__bases__)

 

示例:继承

class People:
    school=oldboy

    def __init__(self,name,age,sex):
        self.name=name
        self.age=age
        self.sex=sex

class Student(People):
    def __init__(self,name,age,sex,num=0):
        # 指明道姓的重用父类中的方法
        People.__init__(self,name,age,sex)
        self.score=num

    def choose_course(self):
        print(%s is choosing course %self.name)

class Teacher(People):
    def __init__(self,name,age,sex,level):
        People.__init__(self,name,age,sex)
        self.level=level

    def score(self,stu,num):
        stu.score=num

stu1=Student(jack,18,male)
print(stu1.__dict__)

teacher1=Teacher(helen,19,female,high)
print(teacher1.__dict__)

 

单继承下的属性查找
自身=》类=》父类。。。
class Foo:
    def f1(self):
        print(Foo.f1)

    def f2(self):
    self.f1()

class Bar(Foo):
    def f1(self):
        print(Bar.f1)


obj1 = Bar()
# => obj1自身找f2,无 =>去类Bar中找f2,无=>去父类Foo中找f2,有
# => f2中obj1.f1 => obj1中找f1,无 =>去类Bar中找f1,有
obj1.f2()
多继承下的属性查找
1.从左往右一个分支一个分支的遍历

特殊情况,棱形继承
python2:深度优先,第一个分支就会找到顶级类
python3:广度优先,最后一个分支找到顶级类,mro()可以查看类的继承顺序
print(Bar.mro())

 

super(类名,对象本身),返回值是一个用来访问父类属性的对象
完全参照mro算法
class School:
    school_name = "mySchool"

    def __init__(self, name, age, sex):
        self.name = name
        self.age = age
        self.sex = sex


class Student(School):
    def __init__(self, name, age, sex, score):
        super(Student, self).__init__(name, age, sex)
        self.score = score
        self.course = []

    def choosing_course(self):
        print(%s is choosing course % self.name)

    def tell_course(self):
        for item in self.course:
            print(%s_%s_%s % (item.c_name, item.c_price, item.c_period))


class Teacher(School):
    def __init__(self, name, age, sex, level):
        super(Teacher, self).__init__(name, age, sex)
        self.level = level

    def give_score(self, stu, num):
        stu.score = num


stu1 = Student(jack, 18, male, 0)

tea1 = Teacher(helen, 19, female, 1)

 

利用组合减少代码冗余
组合指的是一个对象拥有某一个属性,该属性的值是另外一个类的对象
obj=Foo()
obj.attr=Bar()
obj.attr.Bar中的属性
class Course:
    def __init__(self, c_name, c_price, c_period):
        self.c_name = c_name
        self.c_price = c_price
        self.c_period = c_period

    def tell_info(self):
        print(%s_%s_%s % (self.c_name, self.c_price, self.c_period))


course1 = Course(python, 100, 10)
course2 = Course(linux, 200, 20)

stu1.course.append(course1)
stu1.course.append(course2)

stu1.tell_course()

 

多态:同一种事物的多种形态
多态性的特点就是统一
import abc


# 抽象基类,是用来定义规范的,不能够实例化

class Animal(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def speak(self):
        pass


# 子类
class People(Animal):
    def speak(self):
        print(say hello)


# 子类
class Dog(Animal):
    def speak(self):
        print(wangwangwang)


obj1 = People()
obj2 = Dog()


# 定义统一的方法接口
def speak(animal):
    animal.speak()

 

‘‘‘封装
在类内定义的属性前加__开头
这种封装其实是一种变形,并没有真正限制访问
可以通过_dict_查看
__country变成了_People__country

封装数据属性的目的是把属性隐藏起来,不让外部“直接”使用,可以加一些验证之类的事情
封装函数属性的目的:隔离复杂度
class People:
    __country = China

    def __init__(self, name):
        self.__name = name

    def run(self):
        print(%s is running % self.__name)


obj1 = People(jack)
# obj1.run()

print(People.__dict__)
class People:
    def __init__(self, name, age):
        self.__name = name
        self.__age = age

    def tell_info(self):
        print(%s_%s % (self.__name, self.__age))

    def set_info(self, name, age):
        if type(name) is not str:
            print(name format is not right)
            return
        if type(age) is not int:
            print(age format is not right)
            return
        self.__name = name
        self.__age = age


obj1 = People(jack, 18)
# obj1.tell_info()
obj1.set_info(JACK, 18)
# obj1.tell_info()

 

property:把函数属性伪装成数据属性
class People3:
def __init__(self, name, weight, height):
self.name = name
self.weight = weight
self.height = height

@property
def bmi(self):
return self.weight / self.height


obj1 = People3(‘jack‘, 100, 20)

print(obj1.bmi)

 

1.绑定方法
1.1 绑定给对象
1.2 绑定给类
2.非绑定方法
1.1 就是一个普通函数
class Foo:
    def func1(self):
        print(绑定给对象的)

    @classmethod
    def func2(cls):
        print(绑定给类的)

    @staticmethod
    def func3():
        普通方法
反射:通过字符串来操作属性
hasattr()
getattr()
setattr()
delattr()
class Foo:
    def __init__(self, name):
        self.name = name


obj1 = Foo(jack)
print(hasattr(obj1, name))
print(getattr(obj1, name))
setattr(obj1, age, 18)
print(getattr(obj1, age))

 

内置函数:可以重写做一些定制化的功能
__str__ 示例,对象被打印是触发
class Foo:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return <name %s age:%s> % (self.name, self.age)


obj1 = Foo(jack, 18)
obj2 = Foo(helen, 19)
print(obj1)
print(obj2)

__del__ 示例,对象被删除前触发

class Foo:
    def __del__(self):
        print(run del....)


obj = Foo()
print(other code)
使用场景,一旦python代码占有了除python自己的资源,就需要在__del__中释放
#伪代码
class Foo:
    def __init__(self, filename, encoding=utf-8):
        self.f = open(filename, r, encoding=encoding)

    def __del__(self):
        self.f.close()

 

























 

 

 

 

 

 




































































































































以上是关于python学习8_1 面向对象(继承多态封装)以及零散概念(组合,property,绑定方法与非绑定方法,反射,内置函数)的主要内容,如果未能解决你的问题,请参考以下文章

Python学习之旅---封装与反射(类的相关知识,面向对象三大特性:继承-多态-封装)

Python 面向对象

Python面向对象的三大特点:封装,继承和多态

Python 面向对象的三大特性:封装,继承,多态

Python面向对象之类的封装继承与多态

Python学习笔记-面向对象进阶封装多态继承