Python企业面试题3 —— 基础篇
1. py面向对象中的继承有什么特点?
继承概念的实现方式主要有2类:实现继承、接口继承。
实现继承是指使用基类的属性和方法而无需额外编码的能力;
接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力(子类重构爹类方法):
python两种类:经典类 新式类
py3新式类 —— 都默认继承 object class Animal(object): == class Animal:
py2经典类和新式类 并存
class Animal:经典类 —— 继承顺序 个别使用方法
class Animal(object): 新式类
继承分为单继承和多继承
Python是支持多继承的
如果没有指定基类,py的类会默认继承object类,object是所有py类的基类,它提供了一些常见的方法(如__str__
)的实现。
对象可以调用自己本类和父类的所有方法和属性,先调用自己的,自己没有才调用父类的。谁(对象)调用方法,方法中的self就指向谁
class Foo:
def __init__(self):
self.func()
def func(self):
print('Foo.func')
class Son(Foo):
def func(self):
print('Son.func')
s = Son()
s.func()
# -=======================================================
class A:
def get(self):
self.say()
def say(self):
print('AAAAA')
class B(A):
def say(self):
print('BBBBB')
b = B()
b.get() # BBBBB
2. 面向对象中 super 的作用?
# 用于子类继承基类的方法
class FooParent(object):
def __init__(self):
self.parent = 'I\'m the parent.'
print('Parent')
print('1111')
def bar(self, message):
print("%s from Parent" % message)
class FooClild(FooParent):
def __init__(self):
# super(FooChild, self)首先找到FooChild 的父类(就是类FooParent),然后把类B的对象,
# FooChild转换为类FooParent的对象
super(FooClild, self).__init__()
print('Child')
def bar(self, message):
super(FooClild, self).bar(message)
print('Child bar function')
print(self.parent)
if __name__ == '__main__':
foochild = FooClild()
foochild.bar('HelloWorld')
3. 列举面向对象中带双下划线的特殊方法,如:__new__
、__init__
__new__
:生成实例
__init__
:生成实例的属性
__call__
:实例对象加( )会执行def __call__
:...... 方法里面的内容
__del__
:析构方法,当对象在内存中被释放时,自动触发执行。如当del obj或者应用程序运行完毕时,执行该方法里面的内容
__enter__
和__exit__
:出现with语句,对象的__enter__
被处罚,有返回值则赋值给as声明的变量;with中代码块执行完毕时执行 __exit__
里面的内容。
__module__
:表示当前操作的对象在哪个模块 obj.__module__
__class__
:表示当前操作的对象类型是什么 obj.__class__
__doc__
类的描述信息的是,显示print信息无法判断
__str__
:对边对象的字符串显示,显示print函数 obj.__str__()
__repr__
:改变对象的字符串显示,交互式解析器 obj.__repr__()
__format__
:自定义格式化字符串
__slots__
:一个类变量,用来限制实例可以添加的属性的数量和类型
__setitem__
、__getitem__
、__delitem__
:
class Foo:
def __init__(self, name):
self.name = name
def __getitem__(self, item):
print(self.__dict__[item])
def __setitem__(self, key, value):
self.__dict__[key] = value
def __delitem__(self, key):
print('del obj[key]时,我执行')
self.__dict__.pop(key)
def __delattr__(self, item):
print('del obj.key时,我执行')
self.__dict__.pop(item)
f1 = Foo('sb')
f1['age'] = 18
f1['age1'] = 19
del f1.age1
del f1['age']
f1['name'] = 'alex'
print(f1.__dict__)
__get__()
:调用一个属性时触发
__set__()
:为一个属性赋值时触发
__delete__()
:采用del删除属性时触发
4. 如何判断是函数还是方法?
看他的调用者是谁,如果是类,就需要传入一个参数self的值,这时他就是一个函数。如果调用者是对象,就不需要给self传入参数值,这时他就是一个方法。
5. 静态方法和类方法的区别?
尽管 classmethod 和 staticmethod 非常相似,但在用法上依然有一些明显的区别。classmethod 必须有一个指向类对象的引用作为第一个参数,而staticmethod 可以没有任何参数。
# 举个例子:
class Num:
# 普通方法:能够用Num调用而不能用实例化对象调用
def one():
print('1')
# 实例方法:能用实例化对象调用而不能用Num调用
def two(self):
print('2')
# 静态方法:能够用Num和实例化对象的调用
@staticmethod
def three():
print('3')
# 类方法:第一个参数cls长什么样不重要,都是指Num类本身,调用时将Num类作为对象隐式的传入方法
@classmethod
def go(cls):
cls.three()
Num.one() # 1
# Num.two() # 报错
Num.three() # 3
Num.go() # 3
i = Num()
# i.one() # TypeError: one() takes 0 positional arguments but 1 was given
i.two() # 2
i.three() # 3
i.go() # 3
6. 什么是反射?以及应用场景?
反射的核心本质就是以字符串的形式去导入个模块,利用字符串的形式去执行函数。
Django中的CBV就是基于反射实现的。
7. 装饰器的写法以及应用场景?
含义:装饰器本质就是函数,为其他函数添加附加功能
原则:
- 不修改被修饰函数的代码
- 不修改被修饰函数的调用方式
应用场景: - 无参装饰器在用户登录、认证中常见
- 有参装饰器在flask的路由系统中见到过
import functools
def wrapper(func):
@functools.wraps(func)
def inner(*args, **kwargs):
print('我是装饰器')
return func
return inner
@wrapper
def index():
print('我是被装饰函数')
return None
index()
# 应用场景
- 高阶函数
- 闭包
- functools.wraps(func)
8. 异常处理写法以及如何主动抛出异常(应用场景)
# 触发异常
def temp_convert(var):
try:
return int(var)
except ValueError as Argument:
print("参数没有包含数字%s" % Argument)
# 调用函数
temp_convert("xyz")
# 以10为基数的int()的无效文字:“xyz”
# raise 语法
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
try:
raise Networkerror("Bad hostname")
except Networkerror as e:
print(e.args)
9. 什么是面向对象的mro?
mro就是方法解析顺序
10. isinstance作用以及应用场景?
isinstance(对象、类) 判断这个对象是不是这个类或者这个类的子类的实例化
# 判断a属不属于A这个类(可以判断到祖宗类)
class A:
pass
class B:
pass
a = A()
b = B()
print(isinstance(b, A)) # True 判断到祖宗类
# 任何与object都是True,内部都继承object
print(isinstance(a, object)) # True
应用场景:
rest framework 认证的流程
scrapy-redis
11. json序列化时,默认遇到中文会转换成Unicode,如果想要保留中文怎么办?
在序列化时,中文汉字总是被转换为Unicode码,在dumps函数中添加参数ensure_ascii=False即可解决。
12. 简述yield和yield from关键字?
yield和yield from是Python中用于生成器函数的关键字。
(1) yield关键字:
- yield用于定义一个生成器函数,生成器函数可以通过yield语句来产生一个值,并且暂停函数的执行状态,保存当前的上下文环境。
- 当生成器函数被调用时,它会返回一个生成器对象,而不是立即执行函数体内的代码。
- 每次调用生成器对象的__next__()方法或者使用for循环迭代时,生成器函数会从上次暂停的位置继续执行,直到遇到下一个yield语句。
(2) yield from关键字:
- yield from用于在生成器函数内部委托另一个可迭代对象(包括生成器)来产生值。
- 它可以简化生成器函数内部的迭代过程,将迭代的责任交给被委托的可迭代对象。
- 当使用yield from委托一个可迭代对象时,生成器函数会自动处理子生成器的暂停和恢复。
本文来自博客园,作者:生而自由爱而无畏,转载请注明原文链接:https://www.cnblogs.com/zczhaod/p/18117199