Day 24~26 类,面向对象,属性

类:把一类事物的相同的特征和动作整合到一起就是类

对象:就是基于类而创建的一直具体的事物(具体存在的)也是特征和动作整合到一起

 

面向对象:

特征:

动作:

整合到一块

类,用”””类名+.”””取到

数据属性:即变量

函数属性:即函数

查看类的属性dir(类名)

--或-开头为系统内置的类

类名.__dict__[ ]: 查看类的属性字典

实例化

p1=Chinese(‘name’,’18’,’female’)  #立即触发函数def __init__(self,参数)运行

#相当于p1=Chinese.__init__(p1,name,age,gender)

print(p1.__dict__)

类__init__(self,*args)__初始化函数不能用return函数,自动返回self,因为实例化自动return,会造成冲突,初始化函数用来帮类实例化出一个具体对象

def __init__(self,name,addr,type):

self.name=name #实质是self.key=value

 

实例能访问类属性,实例只有函数属性

类在调用自己的函数属性时,self参数为实例

School.func(p1)

 

函数属性命名建议定义:动词+名词:干什么事

类和实例的属性增删改查

实例调用class的方法时会自动传参,若实例自己调自己是不会自动传self参的

###不要修改底层的字典结构,如下代码,不可以这样写

p1.__dict__[‘sex’]=‘male’

print(p1.__dict__)

print(p1.sex)

#可以写p1.sex=‘male’

 

###特定程序写特定的功能的代码,不要混,会造成可读性差,输入输出不要写在函数里,函数只写逻辑,或者把输入输出单独做成函数

###在类中查找

类名.

p1.

在全局查找去掉”.”

在类中定义都在类的字典里,在init中定义都在实例的字典里

p1.l=“C” 在实例中

p1.l.append(‘C’) 在类中加

 

self表示和实例绑定

函数的静态属性

class Fuc:

    @property #目的是调用时看不到内部的逻辑

    def cal_area(self):

           pass

 

r1.cal_area  #调用数据属性

 

 

用类调用类方法

class Fuc:

      @classmethod

      def tell_info(cls,x):

            pass

 

Fuc.tell_info(x)

 

静态方法

class Fuc:

      @staticmethod #类的工具包,不能使用类变量和实例变量

       def wash_body(a,b,c)#无self,不和具体实例绑定

             pass

 

Fuc.wash_body(x,y,z)

 

###组合继承

类和类之间的关联

类的继承

代码之间越独立越好,尽量少做耦合

基类的方法不用实现,目的是规范子类

python3按广度优先查找

Func.__mro__ #查看类的继承顺序,经典类无此方法

super().__init__(父类的参数) #不用写父类,更更新父类名不会影响super()的逻辑

super().do() #不用写self,

###封装

__star#双下划线开头,自动重命名变为_类名__star

__star#双下划线开头默认和用户约定不能调用,隐藏的内部逻辑,但可以在类的内部调用

或可以在内部定义接口函数

def get_id(self):   #访问函数

     print(self.__star)

外部进行如下调用:

p1=get_id()

###反射

hasattr()#判断是否有该属性,返回True/False

func=getattr(p1,’类的属性名’,’如果没有该属性则打印此字符串里的内容’)#返回函数地址

func()

setattr(p1,’key’,’value’) #添加数据属性

setattr(p1,’func’,lambda self:self.name+’abc’) #添加函数属性

 

setattr(p1,’func’,lambda x:x+1) #添加函数属性

p1.func(10)

 

b1.func(b1)

delattr(p1,’key’) #del p1.key #删除属性

 

###动态导入模块

若模块名是字符串,t为m1文件夹下的模块

一般导入方式from m1 import t #相当于拼接路径m1/t

module_t=__import__(‘m1.t’) #拿到的是t

print(module_t)

>>> <module ‘m1’ (namespace)> #返回模块最顶层的文件夹

module_t.t.test1() #调用m1下t模块中的test1函数

_test2() #test2前加一个下划线,为私有,外部不能调用,但不是真正意义的限制,可以通过下面方法调用

from m1.t import _test2

或如下动态导入模块:

import importlib

m=importlib.import_module(‘m1.t’)

print(m)

m.test1()

m._test2()

###__getattr__() 很常用

1.当实例属性不存在时,会调用到类中的def __getattr__(self,item)

p1.aaaaaaaaaaaaaaaaa

2.删除类中的属性会调用到__delattr__(self,item)

del p1.x #触发__delattr__的运行,但并未真正执行删除操作,运用__delattr__可保护类里的属性不被删除

def __delattr__(self,item):

    self.__dict__.pop(item) #即可删除相应属性

3.当设置类属性时会触发__setattr__(slef,key,value)的运行

def __setattr__(self,key,value):

      self.__dict__[key]=value #若改为self.key=value会陷入死循环

f1.z=2

可用dir(类名)查看内置属性

print(f1.__dict__)

>>>{}  #添加属性z=2发现列表为空,并没有执行真正的添加属性操作,需用self.__dict__[key]=value添加属性设置

 

class Foo:

     def __getattr__(self,item):

          print(‘你找到的属性%s不存在‘%item)

 

f1=Foo(‘xyy’)

print(f1.age)  #f1,age对应self,item

>>>你找到的属性age不存在

 

###授权的关键点是覆盖__getattr__

class File:

    def __init__(self,filename,mode=‘re’,encoding=‘utf-8’):

         self.file=open(filename,mode,encoding=endcoing)

    

    def __getattr__(self,item):

        return getattr(self.file,item)  #self.file,file为封装的函数

即使类里File无write,read的方法也可调用read,write

 

posted on 2019-09-24 16:48  进击的许盈盈  阅读(131)  评论(0编辑  收藏  举报