python第9次习题


1、什么是类和实例并说明他们之间的关系


  • 类是一个抽象的概念,一个群体, 拥有共同特征,有类的一些行为;人类

  • 实例
    实例是类的一个具象化体现,类中的一个具体的个体,xx实例属于xx类;

  • 类与实例的关系:

封装

1、实例化
	实例是由类这个抽象的概念实例化而生成的实际个体;
class Person:
	pass

t = Person()
print(t,type(t))
<__main__.Person object at 0x000001C3685DA470> <class '__main__.Person'>
2、类属性、实例属性:
	实例中有实例属性,类中由类的属性,相关属性都存在__dict__属性字典中;
   	实例中调用属性时,首先查看自身的__dict__,没有则去找类的__dict__
class Person:
	age = 27
	def __init__(self,name):
		self.name = name

t = Person('tom')
print(t.name)
print(t.age)
3、类方法
	类中有类方法,实际是一个函数,这个函数中可以实现相应功能;类方法也是属性的一种;

	类方法绑定:类的实例,调用该类中使用类属性定义的的方法时,会出现绑定,将当前实例绑定在了方法上;因为该类的属性方法参数是self,代表实例本身;
class Person:
	def showname(self,name):			#在调用时self代表实例本身;
		self.name = name				#self.name即为实例属性;
		return self.name

t = Person()
t.showname('tom')
初始化方法:在实例化的瞬间会自动完成,将实例赋予一些初始化的配置;
			实例构造首先需要构建实例,然后在进行初始化方法,对实例本身配置;
class Person:
    def __init__(self, name, age, gender):
        self.name = name
        self.age = age
        self.gender = gender

    def showperson(self):
        return self.name, self.age, self.gender


t = Person('zzh', 27, 'man')
print(t.showperson())
		
4、特殊属性:
类有类的特殊属性,实例有实例的特殊属性;
__dict__				#字典,存放的是属性,key为竖向,value为相应的值
__name__				#名字
__class__				#类型
__doc__					#文档属性

5、通过实例去访问属性:

1、首先找自身实例的__dict__,如果自身没有,则取找类的,如果类也没有则抛异常;
2、指定实例名去访问某一个属性,instance.__dict__[key],只能找实例里头的属性;
3、instance.__class__ 返回的是它的类;
   instance__class__.__dict__ 返回的是类的属性
   type(instance) 返回的是实例的类
   
4、可通过实例去找类,但是无法通过类去找实例;
实例存在,类必须存在;
类存在,实例并不是必须存在的,且一个类可以实例化多个实例;

继承

继承的规则:
1、在子类中,可以由自己的属性、方法,也可以继承自父类;
2、关于访问控制:私有的是不能被子类访问的;
本质是修改了名称放在了类的__dict__,只有当前类可以调;
公共的和保护的子类是可以访问的;
3、当父类中有一个方法,子类如果需要使用可以:
#直接使用父类的方法
#重新定义,覆盖父类的方法(重写、覆盖)
#不完全重新定义,在父类的基础上做一些增强(使用super方法去访问父类的类属性)
class Animal:

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

    def jump(self):
        raise NotImplementedError

class Dog(Animal):

    def __init__(self):
        super().__init__('Dog')

    def jump(self):
        return "{} jump ".format(self._name)

class Chicken(Animal):

    def __init__(self):
        super().__init__('Chicken')

    def jump(self):
        return "{} jump jump jump".format(self._name)


d = Dog()
print(d.jump())
c = Chicken()
print(c.jump())

多态

同一套接口(方法)在不同的类型(子类)上,表现的方式不一样就叫多态
多态的前提,有继承,有子类,子类当中有覆盖;
		class Family:
		    def __init__(self, name):
		        self.name = name
		
		
		class Zzh(Family):
		    def showname(self):
		        print(self.name)
		
		
		class Km(Family):
		    def showname(self):
		        print(self.name)

		class Zhy(Family):
			def showname(self):
				print(self.name)
		
		
		f = Zzh('zzh')
		m = Km('km')
		s = Zhy('zhy')
		print(f.showname())
		print(m.showname())
		print(s.showname())

2、类的实例方法、类方法和静态分别如何定义举例说明,并总结它们的应用场景

  • 类的实例方法决定了怎么去定义这个实例,即后续如何调用这个方法(实例调用,还是直接使用类调用)

    第一种:普通方法,可以通过实例化调用,使用类直接调用时需要手动传入实例(类方法绑定)

class A:
	def showme(self):
		return "{}'method".format(self)

#实例调用
t = A()		#有类方法绑定,需要传入self,self代表实例本身
print(t.showme())

#类调用
print(A.showme(t))	#需要手动传入self

适用场景:指通过实例化传入参数保存下来,然后调用这个方法;
需求:需要对一个目录进行相关操作(复制,剪切),首先需要写入源路径、目标路径,然后执行相关动作;
import os
from pathlib import  Path
from shutil import copytree,rmtree

class DirMethod:
    def __init__(self,src:str,dest:str):
        self.src = Path(src)
        self.dest = Path(dest) / str(self.src.name)

    def cp(self):
        if not self.dest.exists():
            copytree(self.src,self.dest)
        else:
            if not self.dest.is_file():
                rmtree(self.dest)
                copytree(self.src, self.dest)
            else:
                os.renames(str(self.dest),str(self.dest) + '.bak')
                copytree(self.src, self.dest)

    def shear(self):
        if not self.dest.exists():
            copytree(self.src,self.dest)
            rmtree(self.src)
        else:
            if not self.dest.is_file():
                rmtree(self.dest)
                copytree(self.src, self.dest)
                rmtree(self.src)
            else:
                os.renames(str(self.dest), str(self.dest) + '.bak')
                copytree(self.src, self.dest)
                rmtree(self.src)

t = DirMethod('E:\py_test','F:')
t.cp()
t.shear()

第二种:类方法装饰器,可通过实例化调用,也可以通过类直接调用;

class A1:
	@classmethod
	def showme(cls):
		return "{}'s method".format(cls)

#实例调用
t = A1()
print(t.showme())

#类调用
print(A1.showme())
使用场景:可以直接通过类去调用方法,也可以通过实例去调用类方法;
需求:时间单位的转换,即可以使用实例化调用方法,也可以直接使用类调用方法;
class Timeconversion:
    def __init__(self,time,unit = 's'):
        self._s = None
        self._m = None
        self._h = None

        if unit == 's':
            self._s = time
        elif unit == 'm':
            self._m = time
            self._s = self.min2sec(self._m)
        else:
            self._h = time
            self._s = self.hours2sec(self._h)

    @property
    def h(self):
        if self._h is None:
            self._h = self.sec2hours(self._s)
            return "{}Hours".format(self._h)
        else:
            return "{}Hours".format(self.sec2hours(self._s))

    @property
    def m(self):
        if self._m is None:
            self._m = self.sec2min(self._s)
            return "{}Minutes".format(self._m)
        else:
            return "{}Minutes".format(self.sec2min(cls._s))

    @property
    def s(self):
        return "{}Seconds".format(self._s)

    @classmethod
    def sec2min(cls,sec):
        cls.sec = sec
        if cls.sec >= 60:
            return "{}Minutes".format(cls.sec / 60)
        else:
            return "{}Seconds".format(cls.sec)

    @classmethod
    def min2sec(cls,min):
        cls.min = min
        return "{}Seconds".format(cls.min * 60)

    @classmethod
    def min2hours(cls,min):
        cls.min = min
        if cls.min >= 60:
            return "{}Hours".format(cls.min / 60)
        else:
            return "{}Minutes".format(cls.min)

    @classmethod
    def hours2min(cls,hours):
        cls.hours = hours
        return "{}Minutes".format(cls.hours * 60)

    @classmethod
    def sec2hours(cls,sec):
        cls.sec = sec
        if cls.sec >= 3600:
            return "{}Hours".format(cls.sec / 3600)

    @classmethod
    def hours2sec(cls,hours):
        cls.hours = hours
        return "{}Seconds".format(cls.hours * 3600)

print(Timeconversion.sec2min(60))
t = Timeconversion(3600,'s')
print(t.s)

第三种:静态方法,与实例、类无关,只是这个方法是属于这个类的;

class A2:
	@staticmethod
	def showme():
		return "static method"

#实例调用:
t = A2()
print(t.showme())

#类调用:
print(A2.showme())


使用场景:方法之间没有任何联系,方法与类也没有关系,只是说这个方法属于这个类;
需求:实现两个数字进行加减乘除的运算;
class Calculator:
    @staticmethod
    def add(x,y):
        return x + y

    @staticmethod
    def sub(x,y):
        return x - y

    @staticmethod
    def ride(x,y):
        return x * y

    @staticmethod
    def excepts(x,y):
        return x / y

t = Calculator()
print(t.add(1,2))

Calculator.add(1,2)


3、MRO是什么,描述其查找顺序

MRO,是方法解析顺序;返回的是一个继承关系;

查找顺序:

实例的__dict__ → 类__dict__ →如果有继承→ 父类 dict

class Person:
    __a = 100
    _b = 200
    c = 300

    def show(self):
        print(self.__a)
        print(self._b)
        print(self.c)


class Zhangzhonghao(Person):
    __a = 10000
    _b = 2000
    c = 3000

a = Zhangzhonghao()
print(a.show())

执行流程:
1、实例化,将变量a赋值给一个实例;
2、实例调用show方法,自身实例的__dict__中没有该方法,找类的,也没有,继续找父类的;
3、找到父类的show方法,执行:

  • 打印self__a,为私有属性,自身实例__dict__没有,找类的__dict__没有,继续找父类的__dict__,self__a 等价于 _Person__a,所以只能使用父类的_Person__a;
  • self._b和self.c,由于在自身类中__dict__中能够找到,所以优先使用自身类中的属性;

4、Mixin是什么,描述其应用场景

mixin类是对一个子类的功能补充,将一个方法抽取出来,然后通过多继承补充到其他的子类中;类似于装饰器;(一个子类缺了啥功能就补啥功能,组合的方式)

	class Doc:
		def __init__(self, content):
			self.content = content
		
	class Word(Doc):
	    pass
	
	
	class Pdf(Doc):
		pass
	
	class PrintableMixin
		def show(self):
			print("** {} **".format(self.content))

	class PrintableWord(PrintableMixin,Word):
		pass

	print(PrintableWord.__bases__)
	print(PrintableWord.mro())
	pw = PrintableWord('666666')
	print(pw.show())

继承关系如图所示:

PrintableWord----->PrintableMixin---->word类---->Doc类---->object
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值