Python面试题总结(9)--高级特性

文章目录

        • 1. 函数装饰器有什么作用?请列举说明?
        • 2. Python 垃圾回收机制?
        • 3. 魔法函数 _call_怎么使用?
        • 4. 如何判断一个对象是函数还是方法?
        • 5. @classmethod 和 @staticmethod 用法和区别
        • 6. Python 中的接口如何实现?
        • 7. Python 中的反射了解么?
        • 8. metaclass 作用?以及应用场景?
        • 9. hasattr()、getattr()、setattr() 的用法
        • 10. 请列举你知道的 Python 的魔法方法及用途。
        • 11. 如何知道一个 Python 对象的类型?
        • 12. Python 的传参是传值还是传址?
        • 13. Python 中的元类 (metaclass) 使用举例
        • 14. 简述 any() 和 all() 方法
        • 15. filter 方法求出列表所有奇数并构造新列表,a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        • 16. 什么是猴子补丁?
        • 17. 在 Python 中是如何管理内存的?
        • 18. 当退出 Python 时是否释放所有内存分配?

1. 函数装饰器有什么作用?请列举说明?

答: 装饰器就是一个函数,它可以在不需要做任何代码变动的前提下给一个函数增加额外功能,启动装饰的效果。 它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。 举例说明一个日志功能的装饰器:

1).首先定义一个log文件

# -*- coding: utf-8 -*-
import os
import time
import logging
import sys
log_dir1=os.path.join(os.path.dirname(os.path.dirname(__file__)),"logs")
today = time.strftime('%Y%m%d', time.localtime(time.time()))
full_path=os.path.join(log_dir1,today)
if not os.path.exists(full_path):os.makedirs(full_path)
log_path=os.path.join(full_path,"facebook.log")
def get_logger():# 获取logger实例,如果参数为空则返回root loggerlogger = logging.getLogger("facebook")if not logger.handlers:# 指定logger输出格式formatter = logging.Formatter('%(asctime)s %(levelname)-8s: %(message)s')# 文件日志file_handler = logging.FileHandler(log_path,encoding="utf8")file_handler.setFormatter(formatter)  # 可以通过setFormatter指定输出格式# 控制台日志console_handler = logging.StreamHandler(sys.stdout)console_handler.formatter = formatter  # 也可以直接给formatter赋值# 为logger添加的日志处理器logger.addHandler(file_handler)logger.addHandler(console_handler)# 指定日志的最低输出级别,默认为WARN级别logger.setLevel(logging.INFO)#  添加下面一句,在记录日志之后移除句柄return  logger

2).然后定义一个装饰器文件
在这里引用wraps,一个装饰器的装饰器,目的为了保持引用进来的函数名字不发生变化

#!/usr/bin/env python 
# encoding: utf-8
from functools import wraps
from logger.log import get_logger
import traceback
def decoratore(func):@wraps(func)def log(*args,**kwargs):try:print("当前运行方法",func.__name__)return func(*args,**kwargs)except Exception as e:get_logger().error(f"{func.__name__} is error,here are details:{traceback.format_exc()}")return log

3)在使用的时候直接在函数上面引用即可

@decorator
def start():print("666")

代码参考来源

2. Python 垃圾回收机制?

答:Python 不像 C++,Java 等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值。对 Python 语言来讲,对象的类型和内存都是在运行时确定的。这也是为什么我们称 Python 语言为动态类型的原因。

主要体现在下面三个方法:

1.引用计数机制 2.标记-清除 3.分代回收
请参考:Python中垃圾回收机制

3. 魔法函数 _call_怎么使用?

答: call 可以把类实例当做函数调用。 使用示例如下
添加链接描述

4. 如何判断一个对象是函数还是方法?

答:看代码已经结果就懂了

from types import MethodType, FunctionType

class Bar:
def foo(self):
pass

def foo2():
pass

def run():
print(“foo 是函数”, isinstance(Bar().foo, FunctionType))
print(“foo 是方法”, isinstance(Bar().foo, MethodType))
print(“foo2 是函数”, isinstance(foo2, FunctionType))
print(“foo2 是方法”, isinstance(foo2, MethodType))

if name == ‘main’:
run()
输出

foo 是函数 False
foo 是方法 True
foo2 是函数 True
foo2 是方法 False

5. @classmethod 和 @staticmethod 用法和区别

答: 相同之处:@staticmethod 和@classmethod 都可以直接类名.方法名()来调用,不用在示例化一个类。 @classmethod 我们要写一个只在类中运行而不在实例中运行的方法。如果我们想让方法不在实例中运行,可以这么做:

def iget_no_of_instance(ins_obj):
return ins_obj.class.no_inst

class Kls(object):
no_inst = 0

def __init__(self):Kls.no_inst = Kls.no_inst + 1

ik1 = Kls()
ik2 = Kls()
print(iget_no_of_instance(ik1))
@staticmethod 经常有一些跟类有关系的功能但在运行时又不需要实例和类参与的情况下需要用到静态方法

IND = ‘ON’

class Kls(object):
def init(self, data):
self.data = data

@staticmethod
def check_ind():return (IND == 'ON')def do_reset(self):if self.check_ind():print('Reset done for:', self.data)def set_db(self):if self.check_ind():self.db = 'New db connection'print('DB connection made for: ', self.data)

ik1 = Kls(12)
ik1.do_reset()
ik1.set_db()

6. Python 中的接口如何实现?

答: 接口提取了一群类共同的函数,可以把接口当做一个函数的集合,然后让子类去实现接口中的函数。但是在 Python 中根本就没有一个叫做 interface 的关键字,如果非要去模仿接口的概念,可以使用抽象类来实现。抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化。使用 abc 模块来实现抽象类。

7. Python 中的反射了解么?

答:Python 的反射机制设定较为简单,一共有四个关键函数分别是 getattr、hasattr、setattr、delattr。

8. metaclass 作用?以及应用场景?

答: metaclass 即元类,metaclass 是类似创建类的模板,所有的类都是通过他来 create 的(调用new),这使得你可以自由的控制创建类的那个过程,实现你所需要的功能。 我们可以使用元类创建单例模式和实现 ORM 模式。

9. hasattr()、getattr()、setattr() 的用法

答:这三个方法属于 Python 的反射机制里面的,hasattr 可以判断一个对象是否含有某个属性,getattr 可以充当 get 获取对象属性的作用。而 setattr 可以充当 person.name = "liming"的赋值操作。代码示例如下:

class Person():
def init(self):
self.name = “liming”
self.age = 12

def show(self):print(self.name)print(self.age)def set_name(self):setattr(Person, "sex", "男")def get_name(self):print(getattr(self, "name"))print(getattr(self, "age"))print(getattr(self, "sex"))

def run():
if hasattr(Person, “show”):
print(“判断 Person 类是否含有 show 方法”)

Person().set_name()
Person().get_name()

if name == ‘main’:
run()

10. 请列举你知道的 Python 的魔法方法及用途。

答:

1 init
类的初始化方法。它获取任何传给构造器的参数(比如我们调用 x = SomeClass(10, ‘foo’) , __init__就会接到参数 10 和 ‘foo’ 。 __init__在 Python 的类定义中用的最多。

2 new
__new__是对象实例化时第一个调用的方法,它只取下 cls 参数,并把其他参数传给 init 。 __new__很少使用,但是也有它适合的场景,尤其是当类继承自一个像元组或者字符串这样不经常改变的类型的时候.

3 del
__new__和 __init__是对象的构造器, __del__是对象的销毁器。它并非实现了语句 del x (因此该语句不等同于 x.del())。而是定义了当对象被垃圾回收时的行为。 当对象需要在销毁时做一些处理的时候这个方法很有用,比如 socket 对象、文件对象。但是需要注意的是,当 Python 解释器退出但对象仍然存活的时候,__del__并不会 执行。 所以养成一个手工清理的好习惯是很重要的,比如及时关闭连接。

11. 如何知道一个 Python 对象的类型?

答:可以通过 type 方法

12. Python 的传参是传值还是传址?

答:Python 中的传参即不是传值也不是传地址,传的是对象的引用。

13. Python 中的元类 (metaclass) 使用举例

答:可以使用元类实现一个单例模式,代码如下

class Singleton(type):
def init(self, *args, **kwargs):
print(“in init”)
self.__instance = None
super(Singleton, self).init(*args, **kwargs)

def __call__(self, *args, **kwargs):print("in __call__")if self.__instance is None:self.__instance = super(Singleton, self).__call__(*args, **kwargs)return self.__instance

class Foo(metaclass=Singleton):
pass # 在代码执行到这里的时候,元类中的__new__方法和__init__方法其实已经被执行了,而不是在 Foo 实例化的时候执行。且仅会执行一次。

foo1 = Foo()
foo2 = Foo()
print(foo1 is foo2)

14. 简述 any() 和 all() 方法

答:
any()与all()函数的区别:any是任意,而all是全部。

any(x):判断 x 对象是否为空对象,如果都为空、0、false,则返回 false,如果不都为空、0、false,则返回 true。

all(x):如果 all(x) 参数 x 对象的所有元素不为 0、’’、False 或者 x 为空对象,则返回 True,否则返回 False。

15. filter 方法求出列表所有奇数并构造新列表,a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

答:

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
b = filter(lambda x: x % 2 == 1, a)
print(b)
print("-------------------------")
print(list(b))

运行结果:

<filter object at 0x000000000267F048>
-------------------------
[1, 3, 5, 7, 9]

其实现在不推荐使用 filter,map 等方法了,一般列表生成式就可以搞定了。

16. 什么是猴子补丁?

答: 猴子补丁(monkey patching):在运行时动态修改模块、类或函数,通常是添加功能或修正缺陷。猴子补丁在代码运行时内存中发挥作用,不会修改源码,因此只对当前运行的程序实例有效。因为猴子补丁破坏了封装,而且容易导致程序与补丁代码的实现细节紧密耦合,所以被视为临时的变通方案,不是集成代码的推荐方式。大概是下面这样的一个效果

def post():
print(“this is post”)
print(“想不到吧”)

class Http():
@classmethod
def get(self):
print(“this is get”)

def main():
Http.get=post #动态的修改了 get 原因的功能,

if name == ‘main’:
main()
Http.get()

17. 在 Python 中是如何管理内存的?

答: 垃圾回收:Python 不像 C++,Java 等语言一样,他们可以不用事先声明变量类型而直接对变量进行赋值。对 Python 语言来讲,对象的类型和内存都是在运行时确定的。这也是为什么我们称 Python 语言为动态类型的原因(这里我们把动态类型可以简单的归结为对变量内存地址的分配是在运行时自动判断变量类型并对变量进行赋值)。

引用计数:Python 采用了类似 Windows 内核对象一样的方式来对内存进行管理。每一个对象,都维护这一个对指向该对对象的引用的计数。当变量被绑定在一个对象上的时候,该变量的引用计数就是 1,(还有另外一些情况也会导致变量引用计数的增加),系统会自动维护这些标签,并定时扫描,当某标签的引用计数变为 0 的时候,该对就会被回收。

内存池机制 Python 的内存机制以金字塔行,1、2 层主要有操作系统进行操作

第 0 层是 C 中的 malloc,free 等内存分配和释放函数进行操作

第 1 层和第 2 层是内存池,有 Python 的接口函数 PyMem_Malloc 函数实现,当对象小于 256K 时有该层直接分配内存

第 3 层是最上层,也就是我们对 Python 对象的直接操作

在 C 中如果频繁的调用 malloc 与 free 时,是会产生性能问题的.再加上频繁的分配与释放小块的内存会产生内存碎片。Python 在这里主要干的工作有:

如果请求分配的内存在 1~256 字节之间就使用自己的内存管理系统,否则直接使用 malloc。

这里还是会调用 malloc 分配内存,但每次会分配一块大小为 256k 的大块内存。

经由内存池登记的内存到最后还是会回收到内存池,并不会调用 C 的 free 释放掉以便下次使用。对于简单的 Python 对象,例如数值、字符串,元组(tuple 不允许被更改)采用的是复制的方式(深拷贝?),也就是说当将另一个变量 B 赋值给变量 A 时,虽然 A 和 B 的内存空间仍然相同,但当 A 的值发生变化时,会重新给 A 分配空间,A 和 B 的地址变得不再相同。

18. 当退出 Python 时是否释放所有内存分配?

答:不是的,循环引用其他对象或引用自全局命名空间的对象的模块,在 Python 退出时并非完全释放。

另外,也不会释放 c 库保留的内存部分

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/451915.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

I/O流讲解

本文来自&#xff1a;曹胜欢博客专栏&#xff1a;http://blog.csdn.net/csh624366188 在软件开发中&#xff0c;数据流和数据库操作占据了一个很重要的位置&#xff0c;所以&#xff0c;熟悉操作数据流和数据库&#xff0c;对于每一个开发者来说都是很重要的&#xff0c;今天就…

Spring Boot入门(9)网页版计算器

介绍 在写了前八篇Spring Boot项目的介绍文章后&#xff0c;我们已经初步熟悉了利用Spring Boot来做Web应用和数据库的使用方法了&#xff0c;但是这些仅仅是官方介绍的一个例子而已。   本次分享将介绍笔者自己的一个项目&#xff1a;网页版计算器&#xff0c;以这两篇博客…

shell编程基础(七): 处理文件命令sed与awk

一、sed&#xff08;以行为单位处理文件&#xff09; sed意为流编辑器&#xff08;Stream Editor&#xff09;&#xff0c;在Shell脚本和Makefile中作为过滤器使用非常普遍&#xff0c;也就是把前一个程序的输出引入sed的输入&#xff0c;经过一系列编辑命令转换为另一种格式输…

数据结构与算法--6.二分查找

文章目录一. 二分查找二. 代码实现一&#xff1a;使用递归三. 代码实现二&#xff1a;非递归一. 二分查找 二. 代码实现一&#xff1a;使用递归 def binary_search(alist, item):"""二分查找&#xff1a;使用递归"""n len(alist)if n > 0:m…

SpringMVC请求处理流程、springMVC工作流程

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 页面请求到来 --> 前端控制器&#xff08;DispatcherServlet&#xff09;收到请求&#xff0c;请求 处理映射器&#xff08;Hanle…

Android的TextView在显示文字的时候,如果有段中文有英文,有中文,有中文标点符号,你会发现,当要换行的时候遇到中文标点, 这一行就会空出很多空格出来...

一、问题描述&#xff1a; Android的TextView在显示文字的时候&#xff0c;如果有段中文有英文&#xff0c;有中文&#xff0c;有中文标点符号&#xff0c;你会发现&#xff0c;当要换行的时候遇到中文标点&#xff0c; 这一行就会空出很多空格出来。原因是&#xff1a; 1&…

什么是IDE

集成开发环境&#xff08;IDE&#xff0c;Integrated Development Environment &#xff09;是用于提供程序开发环境的应用程序&#xff0c;一般包括代码编辑器、编译器、调试器和图形用户界面等工具。集成了代码编写功能、分析功能、编译功能、调试功能等一体化的开发软件服务…

vue 学习

http://jspang.com/ vue 学习 vue 学习 转载于:https://www.cnblogs.com/qianjin888/p/9342031.html

策略模式-Strategy Pattern

解决问题 将算法按照策略或场景封装起来&#xff0c;以方便按照不同的场景执行不同的策略。它很好的解决了通过if...else 来决策行为而带来的代码和逻辑复杂性。 应用场景 一个经常被拿来举例的场景是收银员收银场景&#xff1a;它需要根据不同的场景&#xff08;是否为会员、有…

ssm框架下 tiles框架 的使用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 tiles框架的工作 在springMVC工作流程中属于视图解析器 解析视图这一步。算是视图解析器的一个插件&#xff0c;作了视图解析这步的一部…

数据结构与算法--7.树的基础知识

文章目录一. 树的概念二. 树的术语三. 树的种类四. 树的存储和表示五. 常见的树的应用场景一. 树的概念 二. 树的术语 三. 树的种类 四. 树的存储和表示 五. 常见的树的应用场景

运用java 多线程模拟火车售票。。。。

public class Demo01 { public static void main(String[] args) { // TODO Auto-generated method stub //多线程并行时&#xff0c;会出现的问题 //同步&#xff1a; //买火车票&#xff0c;四个窗口A,B,C,D //创建任务 TicketTask task new TicketTask(); //四个窗口A,B,C,…

JQuery validate 各项验证规则讲解

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 使用样例见&#xff1a;http://blog.csdn.net/jiangyu1013/article/details/56014730 //定义中文消息 var cnmsg { required: “必选字…

数据结构与算法--8.二叉树的基础知识

文章目录一. 二叉树基本概念二. 二叉树的性质三. 二叉树的代码实现四. 二叉树的先序、中序、后序遍历一. 二叉树基本概念 二. 二叉树的性质 三. 二叉树的代码实现 class Node(object):"""二叉树节点"""def __init__(self,item):self.elem item…

ZooKeeper(二)ZooKeeper能做什么?

上一节介绍了ZooKeeper的一些基础知识&#xff0c;这一节主要讲ZooKeeper有哪些用途。命名服务&#xff08;Name Service&#xff09; 主要是作为分布式命名服务&#xff0c;通过调用zk的create node api&#xff0c;能够很容易创建一个全局唯一的path&#xff0c;这个path就可…

jquery vilidate 使用小例

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 // 修改$("#updForm").validate({submitHandler:function(form){new $.flavr({ content : 是否确认修改管理员?,dialog : co…