【InterView】Python部分(一)

目录

基础招式

一行代码实现1-100的和

range的顾头不顾尾,sum函数的运用

print(sum(range(1,101)))
5050

如何在一个函数内部修改全局变量

声明函数体内部变量为全局变量

a=10
def func():
    a=20
    print(a)
func()
print(a)

---结果---
# 20
# 10
a=10
def func():
    global a
    a=20
    print(a)
func()
print(a)

---结果---
# 20
# 20

列出5个python标准库

import os
import sys
import time
import datetime
import random
import re

字典如何删除键和合并2个字典

  • 删除键
    • 方法一:使用pop()
    • 方法二:使用del
    dic = {'a': 1, 'b': 2}
    dic1 = {'c': 3, 'd': 4}
    
    dic.pop('b')
    print(dic)  # {'a': 1}
    
    del dic1['c']
    print(dic1)  # {'d': 4}
  • 合并字典
    dic = {'a': 1, 'b': 2}
    dic1 = {'c': 3, 'd': 4}
    
    dic.update(dic1)
    print(dic)  # {'a': 1, 'b': 2, 'c': 3, 'd': 4}

谈下python的GIL

进程中多线程执行任务是共享进程中的数据的,在单个cpu时间范围内,如果某个线程没有执行完毕,并且没有连续的cpu时间片段,此时后面的线程也开始执行任务,会出现数据混乱的现象,即线程不安全。解决方法:加锁,保证某一时间只有一个线程在执行任务。

2个列表实现列表去重

先利用列表内置函数extend合并,然后集合去重,再转为列表;不保证顺序

li=[2,3,4,5,6]
li1=[4,5,6,7,8]
li.extend(li1)
ll=list(set(li))
print(ll)

fun(*args,**kwargs)中的*args,**kwargs是什么意思

  • *args:接收实际参数中所有没有匹配到的位置参数
  • **kwargs:接收实际参数中所有没有匹配到的关键字参数

一句话解释什么语言能够使用装饰器

可以将函数作为参数进行传参的

python内建类数据类型有那些?

  • str
  • int
  • float
  • bool
  • list
  • tuple
  • dict
  • set

简述面向对象中__new__和__init__区别

  • new
    1. 用于创建对象,将创建的对象给__init__方法
    2. 至少传递一个参数cls,代表当前类
    3. 必须要有返回值,返回实例化出来的实例
  • init:
    1. 用于初始化对象,前提必须创建对象完成,对象创建完成后就立刻被默认调用了,可以接收参数。
    2. 第一个参数位self,就是这个__new__返回的实例;__init__在__new__的基础上可以完成一些其他初始化的动作
    3. __init__不需要返回值
    4. 如果__new__创建的是当前类的实例,会自动调用__init__函数,通过return语句里面调用的__new__函数的第一个参数cls来保证是当前类实例;如果是其他类的类名,那么实际创建返回的是就是其他类的实例,其实就不会调用当前类的__init__函数,也不会调用其他类的__init__函数。

    image

简述with方法打开处理文件帮我们做了什么?

如果使用常规的f.open()写法,我们需要try、except、finally,做异常判断,并且文件最终不管遇到什么情况,都要执行finally f.close()关闭文件。

f=open('./1.txt','w')
try:
    f.write("hello")
except:
    pass
finally:
    f.close()

执行with这个结构之后。f会自动关闭。相当于自带了一个finally。
但是with本身并没有异常捕获的功能,但是如果发生了运行时异常,它照样可以关闭文件释放资源。

with open('a.txt') as f:
    print(f.read())

列表[1,2,3,4,5],请使用map()函数输出[1,4,9,16,25],并且使用列表推导式提取出大于10的数,最终输出[16,25]

map(func, l) : 循环获取列表l的值,并将其传入函数处理

a=[1,2,3,4,5]
def func1(x):
    return x**2

aa=map(func1,a)
new_aa=[i for i in aa if i>10]
print(new_aa)

# 将func1函数简写成匿名函数
l=[1,2,3,4,5]
ll=list(map(lambda x:x*x,l))
lll=[i for i in ll if i>10]
print(lll)

python中生成随机整数、随机小数、0-1之间的小数

random.random():随机生成0到1之间的小数
:.3f:保留3位有效数字

import random

num=random.randint(1,6)
num1=random.random()
print(num)
print(num1)
print('{:.3f}'.format(num1))

python中断言方法举例

a=3
assert(a>1)
print(a)    #3

a=3
assert(a>6)  # 报错
print(a)

"""
Traceback (most recent call last):
  File "D:\log\ceshi_log\face_1.py", line 64, in <module>
    assert(a>6)
AssertionError
"""

列出python中可变数据类型和不可变数据类型,并简述原理

...

去重并从小到大排序输出“adfjl”

s = 'ajldjlajfdljfddd'

s1=list(set(s))
s1.sort()

s2=''.join(s1)
print(s2)

用lambda函数实现两个数相乘

func=lambda a,b:a*b
print(func(3,4))
12

字典根据键从小到大排序

dict1 = {"name": "zs", "city": "beijing", "tel": 1243124}
print(dict1.items())  # dict_items([('name', 'zs'), ('city', 'beijing'), ('tel', 1243124)])

dd = sorted(dict1.items(), key=lambda x: x[0])
print(dd)  # [('city', 'beijing'), ('name', 'zs'), ('tel', 1243124)]

new_dict = {}
for item in dd:
    new_dict[item[0]] = item[1]
print(new_dict)  # {'city': 'beijing', 'name': 'zs', 'tel': 1243124}

利用collections库的Counter方法统计字符串每个单词出现的次数

from collections import Counter

a = "werwerwegdfgerwewed;wer;wer;6"
res = Counter(a)
print(res)  # Counter({'e': 8, 'w': 7, 'r': 5, ';': 3, 'g': 2, 'd': 2, 'f': 1, '6': 1})

filter方法求出列表所有奇数并构造新列表

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


def func(x):
    return x % 2 == 1


newlist = filter(func, a)
newlist = [i for i in newlist]
print(newlist)  # [1, 3, 5, 7, 9]

列表推导式求出列表所有奇数并构造新列表

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
aa = [i for i in a if i % 2 == 1]
print(aa)  # [1, 3, 5, 7, 9]

a=(1,) b=(1) c=(‘1’)分别是什么类型

a=(1,)
b=(1)
c=('1')

print(type(a))  # <class 'tuple'>
print(type(b))  # <class 'int'>
print(type(c))  # <class 'str'>

两个列表合并成一个列表

a = [1, 3, 4, 5, 6]
b = [1, 3, 56, 7, 7, 5]
c = a + b
a.extend(b)
a.sort()
print(c)  # [1, 3, 4, 5, 6, 1, 3, 56, 7, 7, 5]
print(a)  # [1, 1, 3, 3, 4, 5, 5, 6, 7, 7, 56]

[[1,2],[3,4],[5,6]]展开得到[1,2,3,4,5,6]

l = [[1, 2], [3, 4], [5, 6]]


def func(data, new_list):
    for item in data:
        if type(item) != list:
            new_list.append(item)
        else:
            func(item, new_list)


new_list = []
func(l, new_list)
print(new_list)  # [1, 2, 3, 4, 5, 6]

x=“abc”,y=“def” z=[“d”,“e”,“f”],求x.join(y),x.join(z)返回的结果

join():括号里面的是可迭代对象,x插入可迭代对象中间,形成字符串,结果一致

x = "abc"
y = "def"
z = ["d", "e", "f"]

x_1 = x.join(y)
print(x_1)  # dabceabcfabc
x_2 = x.join(z)
print(x_2)  # dabceabcfabc

举例说明异常模块中try except else finally的相关意义

try except else 没有捕获到异常,执行else语句
try except finally 不管是否捕获到异常,都执行finally语句

python中交换2个数值

a = 12
b = 23
a, b = b, a
print(a)  # 23
print(b)  # 12

举例说明zip函数的用法

  1. zip()函数在运算时,会以一个或多个序列(可迭代对象)作为参数,返回一个元组的列表,同时将这些序列中并排的元素配对。
  2. zip()函数可以接收任何类型的序列,同时也可以有2个以上的参数;当传入的参数不同时,zip能自动以最短序列为准进行截取,获取元组。
a = [1, 2, 3]
b = [5, 6, 7]
res = list(zip(a, b))
print(res)  # [(1, 5), (2, 6), (3, 7)]

a = (1, 2)
b = (5, 6, 7)
res2 = list(zip(a, b))
print(res2)  # [(1, 5), (2, 6)]

a = (1, 2, 3)
b = (5, 6, 7)
c = (9, 10, 11, 12)
res1 = list(zip(a, b, c))
print(res1)  # [(1, 5, 9), (2, 6, 10), (3, 7, 11)]

提升python运行效率的方法

  1. 采用生成器,不使用列表和列表推导式,节省大量内存
  2. 多个if elif else 条件语句,把最有可能发生的条件写在最前面,这样可以减少程序判断的次数,提高效率。
  3. 循环代码优化,避免过多重复代码的执行
  4. 多进程、多线程、协程

简述mysql和redis区别

  • redis
    • 内存型非关系数据库
    • 数据保存在内存中,速度快
  • mysql
    • 关系型数据库
    • 数据保存在磁盘中,检索的话,会有一定的IO操作,访问速度相对慢

list=[2,3,5,4,9,6],从小到大排序,不许用sort,输出[2,3,4,5,6,9]

list1 = [2, 3, 5, 4, 9, 6, 1]


def list_str(list):
    num = len(list)
    for i in range(num - 1):
        for j in range(num - 1 - i):
            if list[j] > list[j + 1]:
                list[j], list[j + 1] = list[j + 1], list[j]
    print(list)


list_str(list1)  # [1, 2, 3, 4, 5, 6, 9]  冒泡排序,先把最大的弄最后

写一个单例模式

单例模式是最常使用的一种设计模式,该模式的目的是确保在一个系统中,一个类只有一个实例

class Create_Object:
    obj = None

    def __new__(cls, *args, **kwargs):
        if obj is None:
            cls.obj = super().__new__(cls)
            return cls.obj


object = Create_Object
object1 = Create_Object
print(id(object))  # 140403805279008
print(id(object1))  # 140403805279008

实现保留2位小数

def fn(k, v, div={}):
    div[k] = v
    print(div)


fn("one", 1)  # {'one': 1}
fn("two", 2)  # {'one': 1, 'two': 2}, 因为字典是可变数据类型,所以指向同一个内存地址,传入新的参数后,相当于给字典增加值
fn("three", 3, {})  # {'three': 3}, 传入了一个新字典,所以不再是原先默认的字典

创建字典的方式

a = [("a", 1), ("b", 2), ("c", 3), ("d", 4), ("e", 5)]
A = zip(("a", "b", "c", "d", "e"), (1, 2, 3, 4, 5))
print(dict(A))  # {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}

B = dict([["name", "zs"], ["age", 18]])
C = dict([("name", "ls"), ("age", 20)])
print(B)  # {'name': 'zs', 'age': 18}
print(C)  # {'name': 'ls', 'age': 20}

深拷贝和浅拷贝

  • 浅拷贝:
    • 只拷贝父对象,父对象中的子对象不会进行拷贝
    • 举例

      如果子对象中元素是可变对象,对可变对象进行增删改查操作,拷贝的对象也将进行相应的操作

  • 深拷贝:
    • 父对象和子对象都要拷贝
    • 举例

      如果子对象中元素是可变对象,对可变对象进行增删改查操作,拷贝的对象不变化

  • 特殊
    • 不管是深拷贝还是浅拷贝,如果拷贝前的对象中的元素是不可变对象,拷贝后的对象也将不发生变化

列出几种魔术方法并简要介绍用途

__new__:创建对象
__init__:初始化对象
__str__:返回对实例对象的描述
__dict__:如果是类去调用,表示统计类中所有的类属性和方法;如果是对象去调用,统计的是实例属性
__del__:删除对象执行的方法
__next__:生成器对象去调用,不断的返回生成器中的数据

sort排序和sorted排序的区别,默认参数reverse控制顺序

  • sort:对原列表进行排序,只能对列表进行排序
    f=[1,4,6,3,2,4]
    f.sort()
    print(f)  # [1, 2, 3, 4, 4, 6]
    
    f1=(1,4,6,3,2,4)
    f1.sort()
    print(f1)  # 报错
    
    """
    Traceback (most recent call last):
    File “D:\log\ceshi_log\face_1.py”, line 249, in
    f1.sort()
    AttributeError: ‘tuple’ object has no attribute ‘sort’
    """
  • sorted:对可迭代对象进行排序,排序后产生新的可迭代对象(列表)
    f1 = (1, 4, 6, 3, 2, 4)
    g = sorted(f1)
    print(f1, id(f1))  # (1, 4, 6, 3, 2, 4) 140321011850208
    print(g, id(g))  # [1, 2, 3, 4, 4, 6] 140321279282496
    
    k = "6513251"
    l = sorted(k)
    print(l)  # ['1', '1', '2', '3', '5', '5', '6']
    
    l_1 = sorted(k, reverse=True)
    print(l_1)  # ['6', '5', '5', '3', '2', '1', '1']

使用lambda函数对list排序foo=[-5,8,0,4,9,-4,-20,-2,8,2,-4],正数从小到大,负数从大到小

foo = [-5, 8, 0, 4, 9, -4, -20, -2, 8, 2, -4]
foo1 = sorted(foo, key=lambda x: (x < 0, abs(x)))
print(foo1)  # [0, 2, 4, 8, 8, 9, -2, -4, -4, -5, -20]

列表嵌套字典的排序

foo = [{'name': 'zs', 'age': 18},
       {'name': 'li', 'age': 24},
       {'name': 'ww', 'age': 25}, ]

# 按照姓名排序
foo1 = sorted(foo, key=lambda x: x['name'])
print(foo1)  # [{'name': 'li', 'age': 24}, {'name': 'ww', 'age': 25}, {'name': 'zs', 'age': 18}]

# 按照年领排序
foo2 = sorted(foo, key=lambda x: x['age'], reverse=True)
print(foo2)  # [{'name': 'ww', 'age': 25}, {'name': 'li', 'age': 24}, {'name': 'zs', 'age': 18}]

列表嵌套元组排序,分别对字母和数字进行排序

foo1 = [('zs', 19), ('ls', 18), ('ww', 20)]

foo2 = sorted(foo1, key=lambda x: x[0])
print(foo2)  # [('ls', 18), ('ww', 20), ('zs', 19)]

foo3 = sorted(foo1, key=lambda x: x[1])
print(foo3)  # [('ls', 18), ('zs', 19), ('ww', 20)]

列表嵌套列表排序,年领数字相同怎么办?

foo2 = [['zs', 19], ['ls', 18], ['ww', 20]]
a = sorted(foo2, key=lambda x: x[0])
b = sorted(foo2, key=lambda x: (x[1], x[0]))  # 数字相同按照字母排
print(a)  # [['ls', 18], ['ww', 20], ['zs', 19]]
print(b)  # [['ls', 18], ['zs', 19], ['ww', 20]]

根据键对字典排序

# 方式一
dict1 = {"name": "zs", "city": "beijing", "tel": 1243124}
dict1_1 = sorted(dict1.items(), key=lambda x: x)
print(dict1_1)  # [('city', 'beijing'), ('name', 'zs'), ('tel', 1243124)]

new_dict = {}
for i in dict1_1:
    new_dict[i[0]] = i[1]
print(new_dict)  # {'city': 'beijing', 'name': 'zs', 'tel': 1243124}


# 方式二
dict1 = {"name": "zs", "city": "beijing", "tel": 1243124}
dict1_1 = list(zip(dict1.keys(), dict1.values()))
print(dict1_1)  # [('name', 'zs'), ('city', 'beijing'), ('tel', 1243124)]

dict1_2 = sorted(dict1_1, key=lambda x: x[0])
new_dict = {i[0]: i[1] for i in dict1_2}
print(new_dict)  # {'city': 'beijing', 'name': 'zs', 'tel': 1243124}

根据字符串的长度进行排序

dt = ["name1", "zs", "city", "beijing", "tel"]
dt1 = sorted(dt, key=lambda x: len(x))
print(dt1)  # ['zs', 'tel', 'city', 'name1', 'beijing']

递归求和

def func_sum(number):
    if number >= 1:
        sum = number + func_sum(number - 1)
    else:
        sum = 0
    return sum


print(func_sum(6))  # 21

求n的阶乘

def func_sum(number):
    if number == 1:
        return 1
    else:
        sum = number * func_sum(number - 1)
        return sum


print(func_sum(7))  # 5040

用2种方法去掉空格

# 方法1:
st = " re rt ty"
st1 = st.replace(' ', '')
print(st1)  # rertty

# 方法2:
st2 = st.split(' ')
print(st2)  # ['', 're', 'rt', 'ty']
st3 = ''.join(st2)
print(st3)  # rertty

简述any()和all()方法

  • any():只要迭代器对象中有一个元素为真就为真
  • all():迭代器中所有的判断项返回都是真,结果才为真
data = [1, 4, 6, 3, 7, 0]
print(any(data))  # True

data1 = [1, 0, 0, 0]
print(any(data1))  # True

data2 = [0, 0, 0, 0]
print(any(data2))  # False
data = [1, 4, 6, 3, 7, 8]
print(all(data))  # True

data1 = [1, 0, 0, 0]
print(all(data1))  # False

data2 = [0, 0, 0, 0]
print(all(data2))  # False

常见的异常

IOError:输入输出异常
AttributeError:试图访问一个对象没有属性
ImportError:无法引入模块和包,,基本是路径的问题
IndentationError::语法错误,代码没有正确的对齐
IndexError:下标索引超出序列边界
KeyError:试图访问字典中不存在的键
SyntaxError:代码逻辑语法错误,不能执行
NameError:使用一个还未赋予对象的变量

简述同源策略

同源政策的⽬的,是为了保证⽤户信息的安全,防⽌恶意的⽹站窃取数据。

  • 同源策略需要同时满足3点要求
    • 协议相同
    • 域名相同
    • 端口相同
  • 举例说明

    http://www.example.com/dir/page.html

    • 协议是 http://
    • 域名是 www.example.com
    • 端⼝是 80(默认端⼝可以省略)image

简述悲观锁和乐观锁

  • 悲观锁:每次去拿数据的时候都认为别人会去修改,所以每次拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里面就用到了很多这种锁机制,比如行锁、表锁、读锁、写锁等,都是在操作之前先上锁
  • 乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有更新这个数据,可以使用版本号机制。

分别从前端、后端、数据库阐述web项目的性能优化

  • 前端:

    html和css放在页面的上部,javascript放在页面下方,因为javascript加载比html和css加载慢,所以要优先加载html和css,以防页面显示不全,性能差,影响用户体验。

  • 后端:
    1. 对于缓冲存储读写次数高、变化少的数据,比如网站首页的信息。应用程序读取数据时,一般是先从缓冲中给读取,如果读取不到或者数据已经失效,再访问磁盘数据库,并将数据再次写入缓冲。
    2. 异步方式,如果有耗时操作,采用异步,celery
    3. 代码优化,避免循环和判断次数太多,如果有多个if else判断,优先判断最有可能先发生的情况。
  • 数据库优化:
    1. 如有条件,数据可以存放redis,读取速度快
    2. 建立索引、外键

举例说明SQL注入和解决办法

当以字符串格式化形式输入时,如果用户输入带有;+SQL语句的时候,后面的SQL语句就会执行

image

解决方式:通过传参方式解决SQL注入

image

python垃圾回收机制

主要以引用计数为主,标记清除和分代清楚为辅的机制

  • 引用计数算法

    当有1个变量保存了对象的引用时,此对象的引用计数就会加1;
    当使用del删除变量指向的对象时,如果对象的引用计数不为1,比如3,那么此时只会让引用计数减1,即变为2;
    当再次调用del时,变为1;
    如果再调用1次del,此时会真的把对象进行删除。

    image

给定2个字符串A=“abcdefg”,B=“abfyt”,得到两个字符串中相同字符组成新的字符串

A = "abcdefg"
B = "abfyt"

list = []
for i in A:
    for j in B:
        if i == j:
            list.append(i)

res = ''.join(list)
print(res)  # abf

输入日期, 判断这一天是这一年的第几天?

import datetime


def func():
    year = input('请输入年份:')
    month = input('请输入月份:')
    day = input('请输入天:')
    date1 = datetime.date(year=int(year), month=int(month), day=int(day))  # 2023-02-17
    date2 = datetime.date(year=int(year), month=1, day=1)
    return (date1 - date2).days + 1


res = func()
print(res)  # 48

现有字典 d={} 请按value值进行排序?

d = {"laker": "kobe", "calc": "james", "golden": "curry"}

dd = sorted(d.items(), key=lambda x: x[1])  # [('golden', 'curry'), ('calc', 'james'), ('laker', 'kobe')]

new_dict = {}
for item in dd:
    new_dict[item[0]] = item[1]
print(new_dict)  # {'golden': 'curry', 'calc': 'james', 'laker': 'kobe'}

字典推导式

D = {i[0]: i[1] for i in [["a", "b"], ["c", "d"]]}
print(D)  # {'a': 'b', 'c': 'd'}

将字符串 “k:1 |k1:2|k2:3|k3:4”,处理成字典

s = "k:1|k1:2|k2:3|k3:4"


def func(str_num):
    new_dict = {}
    for items in str_num.split("|"):
        key, value = items.split(":")
        new_dict[key] = value
    print(new_dict)


func(s)  # {'k': '1', 'k1': '2', 'k2': '3', 'k3': '4'}

请按alist中元素的age由大到小排序

alist = [{'name': 'a', 'age': 20}, {'name': 'b', 'age': 30}, {'name': 'c', 'age': 25}]
alist_1 = sorted(alist, key=lambda x: x['age'], reverse=True)
print(alist_1)  # [{'name': 'b', 'age': 30}, {'name': 'c', 'age': 25}, {'name': 'a', 'age': 20}]

下面代码的输出结果将是什么?

代码将输出[],不会产生IndexError错误,就像所期望的那样,尝试用超出成员的个数的index来获取某个列表的成员。例如,尝试获取list[10]和之后的成员,会导致IndexError,然而,尝试获取列表的切片,开始的index超过了成员个数不会产生IndexError,而是仅仅返回一个空列表。这成为特别让人恶心的疑难杂症,因为运行的时候没有错误产生,导致Bug很难被追踪到。

list = ['a', 'b', 'c', 'd', 'e']
print(list[10:])  # []

写一个列表生成式,产生一个公差为11的等差数列

print([x * 11 for x in range(10)])  # [0, 11, 22, 33, 44, 55, 66, 77, 88, 99]

给定两个列表,怎么找出他们相同的元素和不同的元素?

list1 = [1, 3, 5, 7, 11]
list2 = [2, 3, 4, 5, 6, 7]
set1 = set(list1)
set2 = set(list2)
li = list(set1 & set2)
li1 = list(set1 ^ set2)

print(li)  # [3, 5, 7]
print(li1)  # [1, 2, 4, 6, 11]

请写出一段python代码实现删除list里面的重复元素

  • 利用集合的去重
    lis = [1, 2, 1, 2, 3, 5, 7, 4, 2]
    lis1 = list(set(lis))
    print(lis1)  # [1, 2, 3, 4, 5, 7]
  • 列表逐个in
    lis = [1, 2, 1, 2, 3, 5, 7, 4, 2]
    
    lis1 = []
    for i in lis:
        if i not in lis1:
            lis1.append(i)
    print(lis1)  # [1, 2, 3, 5, 7, 4]

反转一个整数,例如-123 --> -321

l = -213


def func(num):
    num = str(num)
    if num[0] == "-":
        new_num = "-" + num[1:][::-1]
        return int(new_num)
    new_num = num[::-1]
    return int(new_num)


print(func(l))  # -312

用一行python代码写出1+2+3+10248

num = sum([1, 2, 3, 4, 5])
print(num)  # 15
from functools import reduce

num1 = reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
print(num1)  # 15

一句话解决阶乘函数

from functools import reduce

num = reduce(lambda x, y: x * y, range(1, 6))
print(num)  # 120

面向对象中怎么实现只读属性?

将对象私有化,通过共有方法提供一个读取数据的接口

class person:
    def __init__(self, x):
        self.__age = 10

    def age(self):
        return self.__age


t = person(22)
# t.__age =100
print(t.age())  # 10

最好的方法

class MyCls(object):
    __weight = 50

    @property
    def weight(self):
        return self.__weight


obj = MyCls()
print(obj.weight)  # 50

什么是lambda函数? 有什么好处?

lambda 函数是一个可以接收任意多个参数(包括可选参数)并且返回单个表达式值的函数

  1. lambda函数比较轻便,即用即仍,很适合需要完成一项功能,但是此功能只在此一处使用,连名字都很随意的情况下
  2. 匿名函数,一般用来给filter,map这样的函数式编程服务
  3. 作为回调函数,传递给某些应用,比如消息处理

递归函数停止的条件?

递归的终止条件一般定义在递归函数内部,在递归调用前要做一个条件判断,根据判断的结果选择是继续调用自身,还是return,返回终止递归。

  1. 判断递归的次数是否达到某一限定值
  2. 判断运算的结果是否达到某个范围等,根据设计的目的来选择
    def func_sum(number):
        if number >= 1:
            sum = number + func_sum(number - 1)
        else:
            sum = 0
        return sum
    
    
    print(func_sum(6))

写一个匿名函数求两个数的和

sum = lambda a, b: a + b
print(sum(3, 4))

对装饰器的理解,使用装饰器来给所有的work增加记录日志的功能

import time


class Logs:

    def __init__(self, log_file, level):
        self.log_file = log_file
        self.level = level

    def __call__(self, func, *args, **kwargs):
        def write_logging(*args, **kwargs):
            log = f'[{self.level}--时间是:{time.strftime("%H:%M:%S", time.localtime())}]'
            print(log)  # [info--时间是:22:23:52]
            with open(self.log_file, 'a') as f:
                f.write(log + '\n')
            func(*args, **kwargs)

        return write_logging


@Logs(log_file='out.log', level='info')
def work():
    print('我在工作')


work()

对列表进行乘积运算

对列表进行乘积运算的结果相当于对列表的数据进行复制拷贝到当前列表中

list = [3, 6, 9, 1]
print(list * 2)  # [3, 6, 9, 1, 3, 6, 9, 1]

Python 中列表和元组的区别是什么?元组是不是真的不可变?

  • 列表可变,元组不可变
  • 元组的查询速度比列表快
  • 列表能进行增删改查操作,元组不可以进行增加操作
  • 列表不可以作为字典的键,元组可以作为字典的键

什么是生成器和迭代器?它们之间有什么区别?

  • 生成器
    • 生成器包括列表生成器和函数中加入yield生成器
    • 生成器并不是列表,它保存了如何生成生成器中元素的算法
    • 解决了列表或者是列表生成式的缺点,解决了大量无用数据占用资源的问题
    • 生成器中含有游标,记录了元素的位置,下次使用数据时,会继续去取数据
  • 迭代器
    • 通过调用__next__()方法能不断生成下一个数据的方式,就是迭代器

什么是闭包?装饰器又是什么?装饰器有什么作用?

  • 闭包:
    • 闭包需要满足3个条件:
      • 函数中嵌套函数
      • 内部函数中调用外部函数中的变量
      • 外部函数要返回内部函数中的函数名
    • 内部函数不能修改外部函数中变量,如果非要修改用关键字nolocal
  • 装饰器
    • 不改变原函数的功能,增加新的功能
    • 在使用装饰器的方法上加@函数名或者类名
    • 装饰器分为函数装饰器和类装饰器

在学习 Python 的过程中,你有想过如何提高 Python 的运行效率吗?

  • if elif … else:语句中,尽量把执行几率高的语句放到最上面,减少代码的执行
  • for、while循环语句中,尽量减少代码的循环测试
  • 不定义列表或者列表生成式,采用列表生成器,减少内存中无用数据的堆积
  • 采用多线程,异步方式执行
  • 减少不必要的代码执行
  • 减少不必要的IO操作

Python 里 match 与 search 的区别?

  • match()和search()两者都是测试正则表达式与字符串是否匹配。

  • 不同的是

    • match() 如果在字符串的开头有0个或更多个字符,符合正则表达式模式,返回相关匹配的实例对象;如果字符串不符合正则表达式模式则返回None;
    • 而search()则不同,扫描整个字符串,如果产生了一个匹配正则模式就寻找到这个位置,返回相关匹配的对象。如果没有位置能够匹配这个模式则返回None。
    import re
    str="谢谢您的关注和支持:YZL123"
    result=re.match('123',str)
    result1=re.match('谢您',str)
    result2=re.match('谢谢您',str)
    print(result)  # None
    print(result1)  # None
    print(result2)  # <re.Match object; span=(0, 3), match='谢谢您'>
    print(result2.group())  # 谢谢您
    import re
    
    str = "谢谢您的关注和支持:YZL123"
    result3 = re.search('123', str)  # <re.Match object; span=(13, 16), match='123'>
    print(result3)
    result4 = re.search('1234', str)  # None
    print(result4)

is和==有什么区别?

  • is

    比较的是两个对象的id值是否相等,也就是比较俩对象是否为同一个实例对象。是否指向同一个内存地址

  • ==

    比较的两个对象的内容/值是否相等,默认会调用对象的eq()方法

简述read、readline、readlines的区别?

  • read 读取整个文件
  • readline 读取下一行
  • readlines 读取整个文件到一个迭代器以供我们遍历

Python中yield的用法?

yield就是保存当前程序执行状态。 你用for循环的时候,每次取一个元素的时候就会计算一次。用yield的函数叫generator,和iterator一样,它的好处是不用一次计算所有元素,而是用一次算一次,可以节省很多空间,generator每次计算需要上一次计算结果,所以用yield,否则一return,上次计算结果就没了

Python异步使用场景有那些?

  1. 不涉及共享资源,获对共享资源只读,即非互斥操作
  2. 没有时序上的严格关系
  3. 不需要原子操作,或可以通过其他方式控制原子性
  4. 常用于IO操作等耗时操作,因为比较影响客户体验和使用性能
  5. 不影响主线程逻辑

可变类型和不可变类型

  • 可变类型—>不可 hash 类型
    • 列表 list
    • 字典 dict
    • 集合 set
  • 不可变类型–>可hash类型
    • 整数 int
    • 字符串 str
    • 浮点数 float
    • 布尔类型 bool
  • 说明
    1. 当进行修改操作时,可变类型传递的是内存中的地址,也就是说,直接修改内存中的值,并没有开辟新的内存。
    2. 不可变类型被改变时,并没有改变原内存地址中的值,而是开辟一块新的内存,将原地址中的值复制过去,对这块新开辟的内存中的值进行操作。

read、readline、readlines的区别

read

可以一次性读取文件中所有内容

  • file.read():会将所有的内容读取出来,默认是从文件的头部开始读取的。
    with open('1.txt','r') as file:
        content=file.read()
        print(content)
  • file.seek(offset[,whence]):将文件的指针移动到新的位置
    • file:表锁已经打开的文件
    • offset:用于指定移动的字符个数
    • whence:用于指定从什么位置开始计算,值为0表示从文件头开始计算,1表示从当前位置开始计算,2表示从文件末尾开始计算,默认为0
      with open('1.txt','r') as file:
          file.seek(22)  # 先将指针从头向后移动22个字符
          content=file.read()
          print(content)
  • file.read(size):表示读取size个字符
    with open('1.txt','r') as file:
        file.seek(22)
        content=file.read(10)  # 包括回车、空格
        print(content)

readline

每次读取一行数据,每访问一次,向下走一行

  • 通过循环将文件中的数据全部读取出来
    with open('1.txt','r') as file:
        number=0
        while True:
            number+=1
            content=file.readline()
            if content=='':
                break
            print(number,content,end='\n')

readlines

读取全部行,返回的是一个字符串列表,每个元素为文件的一行内容

  • 将列表元素逐行输出
    with open('1.txt','r') as file:
        content=file.readlines()
        for index,item in enumerate(content):
            print(index+1,item)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Al6n Lee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值