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,绑定方法与非绑定方法,反射,内置函数)的主要内容,如果未能解决你的问题,请参考以下文章