1、类可以添加一个自定义的内置函数吗?
答:不可以。内置函数是Python解释器的一部分,要阉割控制其数量。(但是可以重写内置函数)
2、多继承时,构造方法的调用情况?
答:根据MRO列表进行调用。具体原则如下:
2.1 子类永远在父类前面;
2.2 若多个父类中存在相同的方法,则调用第一个父类的方法。
class Base(object):
def __init__(self):
print("enter Base")
print("leave Base")
class ClassA(Base):
def __init__(self):
print("enter ClassA")
super().__init__()
print("leave ClassA")
class ClassB(Base):
def __init__(self):
print("enter ClassB")
super().__init__()
print("leave ClassB")
class DemoClass(ClassA, ClassB):
def __init__(self):
print("enter DemoClass")
super().__init__()
print("leave DemoClass")
dc = DemoClass()
'''
输出如下:
enter DemoClass
enter ClassA
enter ClassB
enter Base
leave Base
leave ClassA
leave ClassB
leave DemoClass
'''
3、type()的作用?
答:运行时,动态创建类。MyClass = type(name, bases, attrs)。
# 3.1 获取对象的类型
print(type(1)) # ===>> <type 'int'>
# 3.2 运行时,动态创建类(重点)。接收如下三个参数:
# name: 类名
# bases: 一组"类的父类"的元组。
# attrs: 类的相关属性、方法。| (结合反射理解)
MyClass = type('className', (), {}) # 'className'是你的类名
# =====>>> 等价于
class MyClass(object):
pass
4、metaclass是什么?(更多参考此处)
答:元类。本质上是一个类。用来创建一个类对象的类。可以定制类对象的创建过程。
# # 利用元类创建我们需要的类
# 1、通过继承type,创建MetaClass
'''
要点:
1、必须显式地继承type
2、必须实现__new__()
'''
class MyMetaClass(type): # type的作用结合上述第3点
'''
cls:要动态修改的类
name:新的类名
bases:继承的父类
attrs:新的属性、方法
'''
def __new__(cls, name, bases, attrs):
'''必须实现new()'''
attrs['name'] = '自定义的类'
attrs['show'] = func() # 此处func是一个示例的函数,实际情况应改为自己的函数
return super().__new__(cls, name, bases, attrs)
# 2、通过指定元类,来创建我们所需的类
class DemoClass(object, metaclass=MyMetaClass):
'''
metaclass=MyMetaClass,代表使用MyMetaClass来创建所需的类。
默认创建MyMetaClass中attrs中的属性和方法
'''
pass # 什么都不写,看看其默认创建的哪些属性、方法。
dc = DemoClass()
print("name: ", dc.name) # 输出"自定义的类"
print("show: ", dc.show()) # 返回func的结果
完整实例代码参考此处:https://gitee.com/jieTan/design_mode_python_version/blob/master/demoTest/metaclassDemo.py
5、垃圾回收的原理?(必须掌握的面试点!)
垃圾回收的策略:以 引用计数 为主,标记-清楚 和 分代回收 为辅。
5.1 引用计数:(表示引用该对象的数量)
Python中每个对象内部都有一个引用计数对象ob_refcnt。当某个对象的引用计数为0时,
表明已经没有任引用指向该对象,于是该对象就要被垃圾会回收了。(缺点:无法回收循环引用的对象)
5.2 标记清除:(一般针对list、dict、class等容器对象)(更多详情)
针对循环引用而制定的回收策略。既是两个对象互相引用对方本体或者是对方的属性,除此之外,再没有
其他对象对其有引用关系。等到没有内存的时候,扫描整个程序栈,遍历以对象为节点,引用为边的图。
对所有可达的节点打上标记,把不可达的节点释放。
5.3 分代回收:(也称"弱代假说")
根据对象存活的时间,将对象划分成不同的集合(代)。每个代对应一个链表。
默认分为3代,即幼年代(第0代),青年代(第1代),老年代(第2代)。
代数越大,gc对其访问频率就越小。
"分代回收"依赖"标记清除"的策略。
回收触发时机:
1)使用gc模块,调用gc.collect()时。
2)当gc模块的计数器达到阈值的时候。Python解释器中存在"被创建的对象计数 as Created"
和"已释放对象计数 as Released",当Created与Released的差异超过了某个阈值,则会触发垃圾回收。
3)程序退出的时候。
6、内存管理的原理?
管理机制有如3中:1)引用计数、2)垃圾回收、3)内存池。(引用计数、垃圾回收见上述第5点)
3)内存池:管理对小块内存的申请和释放。(更多详情)
预先在内存中申请一定数量的,大小相等的内存块做备用。当申请小块内存(一般小于256K)时,
直接使用内存池中的内存块,而不用去调用底层的c去申请内存。
6、什么是函数闭包?(代码示例)
1、定义:在一个函数的内部,对外部作用域(但不是全局作用域)的变量进行引用。
那么此内部函数就别认为是闭包。
2、注意项:对外部变量是引用,不能是修改。
3、作用:
1)当闭包函数运行结束后,其外部的运行环境不会改变(因为不会修改外部的变量值)。
2)根据外部的变量,可实现不同的配置方案。
7、魔法函数。(__new__(), __init__(), __doc__()之类的)
7.1)定义说明:python对象默认实现和自动调用的函数。
1、是系统自动调用的函数。
比如 print(实例),则会自动调用 实例.__str__() 进行返回、输出。
2、是内置函数的底层函数。
比如len(), len(object)实际上是调用object实现的__len__()。
比如 a > b,实际是调用a.__gt(b)。
7.2)重点魔法函数:
7.3 )自定义魔法函数:
8、装饰器的本质?
本质是一个函数。让其他函数在不修改代码的情况下,增加额外的功能。
9、函数与方法的区别?(更多参考此处)
函数独立存在,方法必须依赖(绑定)一个对象。
9.1)从依赖上区分:(重点)
a)函数:独立存在,不需要某个对象来进行调用。即"func()"
b)方法:必须依赖于对象的调用。即:"对象.方法"。
(class的静态方法是函数,类方法依赖cls,实例方法依赖于self)
10、判断某个对象是不是函数的方法?