Python高级部分(一)

一 元类

1.1 什么是元类?

①元类是类的类,是类的模板;
②元类是用来控制如何创建类的,正如类是如何创建对象的模板一样;
③元类的实例为类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象;
答案
#创建类的第一种方式
class Foo:
    def __init__(self,name):
        self.name=name
print(Foo)
print(Foo.__dict__)

#创建类的第二种方式
def __init__(self,name,age):
    self.name=name
    self.age=age
def test(self):
    print('这是test方法')
#type需要传三个参数:①类名,②父类(可以有多个父类,所以是个元组)③所创建类的属性和方法
FFo=type('FFo',(object,),{'x':1,'__init__':__init__,'test':test})
print(FFo)
print(FFo.__dict__)
f=FFo('AA',18)
f.test(
创建类的两种方式
①一个类没有声明自己的元类,默认它的元类就是type.除了使用内置元类type,也可以通过继承type来自定义元类,然后使用metaclass关键字参数为一个类指定元类;

 ②自定义元类可以控制类的产生过程,类的产生过程其实就是元类的调用过程即FFo=Mymeta('FFo',(object,),{...}),调用Mymeta会先产生一个空对象FFo,然后连同调用Mymeta括号内的参数一同传给Mymeta下的__init__方法,完成初始化,如下所示:


class Mymeta(type):#只有继承了type类才能称之为一个元类,否则就是一个普通的自定义类
    def __init__(self,class_name,class_base,class_dic):
        # print(class_name)#FFo
        # print(class_base)#(<class 'object'>,)
        # '''
        # {'__module__': '__main__', '__qualname__': 'FFo', '__doc__': '\n    注释文档\n    ',
        #  '__init__': <function FFo.__init__ at 0x000001ADD9106730>}
        # '''
        # print(class_dic)
        super(Mymeta,self).__init__(class_name,class_base,class_dic)#重用父类功能
        if class_name.islower():
            raise TypeError('类名%s请修改为驼峰体'%class_name)
        if '__doc__' not in class_dic or len(class_dic['__doc__'].strip(' \n')) ==0:
            raise TypeError('类中必须有文档注释,并且文档注释不能为空')

class FFo(object,metaclass=Mymeta):#FFo=Mymeta('FFo',(object,),{...})
    '''
    注释文档
    '''
    school='郑大'
    def __init__(self,name,age):
        self.name=name
        self.age=age

元类初始化过程
自定义元类

1.2 Python中类方法,类实例方法,静态方法的区别?

类方法:是类对象的方法,在定义时需要在上方使用"@classmethod"进行装饰,形参为cls.表示类对象,类 对象和实例对象都可调用类方法;

类实例方法:是类实例化对象的方法,只有实例对象可以调用,形参为 self,指代对象本身;

静态方法:是一个任意函数,在其上方使用“@staticmethod”进行装饰,可以用对象直接调用.静态方法实际上跟该类没有太大关系,类和实例对象都可调用静态方法

#拓展
类属性,直接在类中定义的属性,类属性可以通过类对象来修改,无法通过实例对象修改
实例属性,通过实例对象添加的属性,实例属性只能通过实例对象来访问和修改,类对象无法访问修改

class Demo_Property:
    #类属性
    class_name = "Demo_Poperty"
    
    def __init__(self,x=0):
        self.x = x #实例属性
    def chng(self,x): #修改实例属性的方法
        self.x=x      #注意实例属性的引用方式

    def chng_cn(self,name): #修改类属性的方法
        Demo_Property.class_name = name #注意类属性的引用方式

#属性访问
在类中定义的名字,都是类的属性,细说的话,类有两种属性:数据属性和函数属性(即方法),可以通过__dict__访问属性的
class Student:
    school='清华大学'
    def __init__(self,name):
        self.name = name
    def choose(self):
        pass

Student.school#访问数据属性,等同于Student.__dict__['school']
Student.choose#访问函数属性,等同于Student.__dict__['choose']
#除了查看属性外,还可以使用Student.attrib=value(修改或新增属性),用del Student.attrib删除属性
#---------------操作对象属性-----------------
stu1 = Student('李明')
stu1.name #查看,等同于stu1.__dict__['name']
stu1.age=26 #新增,等同于stu1.__dict__['age']=26
stu1.name='AA'#修改等同于stu1.__dict__['name']='AA'
del stu1.age #删除,等同于del stu1.__dict__['age']
答案及拓展

1.3 Python中如何动态获取和设置类的属性

可以通过反射动态获取和设置对象的属性
if hasattr(Foo,"x"):
    print(getattr(Foo,'x'))
    setattr(Foo,'x',6)
print(getattr(Foo,'x'))
delattr(Foo,'x')
print(getattr(Foo,'x'))
答案

 

二 内存管理与垃圾回收机制

2.1 Python的内存管理机制及调优手段

   在定义了变量x=10,会在内存中的栈区开辟一个x的名称空间,同时也会在内存的堆区开辟一个内存空间存放10这个数值,而x = 10相当于把x指向了10的内存地址;
    
    同时把x指向10称为,10被引用了1次;
    如果再定义y = 10,同时,y也指向了10的内存地址,加上前面的x,10这个数值同时被x和y引用,也就是被引用了2次;
    计算对象被引用的次数,称为引用计数
    引用计数是一种非常高效的内存管理手段,当一个Python对象被引用时其引用计数增加 1, 当其不再被一个变量引用时则计数减 1. 当引用计数等于 0 时对象被删除。
增加引用计数的方式:
①对象被创建,如x=1,此时变量名x指向对象1,对象1的引用计数为1.
②别名被创建,如y=x,此时变量名y也指向对象1,对象1的引用计数为2.
③被作为参数传递给函数,function(x)
④称为容器对象(列表,元组,字段)中的元素

减少引用计数的方式:
①变量名指向另一个对象:x=1;y=x;y=2,本来变量名x,y都指向对象1,引用次数为2,当把对象2赋值给变量名y时,变量名y不再指向对象1,此时引用次数变为1
②函数结束时,比如function(x)结束后,对象1的引用次数减少1次
③显示删除别名,如del y
④从容器对象中移除或者容器对象被删除list.remone(x)或del liet






       
     
内存管理
在Python中维护了一个refchain的双向链表,这个链表中存储程序创建的所有对象,每种类型的对象中都有一个ob_refcnt引用计数器的值,最后当引用计数器的值为0时会进行垃圾回收(对象销毁,refchain中移除).

但是在Python中对于那些可以有多个元素组成的对象可能会存在循环引用的问题,为了解决这个问题,Python又引用了标记清除和分代回收,在其内部创建四个链表
①refchain
②2代 (阈值 1次扫描10次)
③1代(阈值 0代扫描10次)
④0代(阈值 0代链表中的元素超过700个)
在源码内部当达到各自的阈值时,就会触发扫描链表进行标记清除的动作(有循环则各自减1)

But,在源码在上述的流程中提出了优化机制,就是缓存.
答案

 

posted on 2021-01-09 22:52  rwwh  阅读(93)  评论(0)    收藏  举报

导航