1 python的8种数据类型并分别列出你会的方法?
整数类型(int):不可变类型。例如:1。
浮点数型(float):不可变类型。例如:2.3。
Boolean(布尔值)与空值:不可变类型。布尔值只有True和False。空值为None。
字符串(String):字符串是一种有序的、不可变的字符序列,用于表示文本数据。字符串可以使用单引号、双引号或三引号来表示,例如:'hello'、"world"、'''Python'''。
列表(List):列表是一种有序的、可变的数据集合,可以存储任意类型的数据,通过索引访问。列表使用方括号 [] 表示,例如:[1, 2, 3, 'a', 'b', 'c']。
元组(Tuple):元组是一种有序的、不可变的数据集合,类似于列表,但元组的元素不可修改。元组使用圆括号 () 表示,例如:(1, 2, 3, 'a', 'b', 'c')。
字典(Dictionary):字典是一种无序的、可变的键值对集合,每个键值对之间用逗号分隔,键值对使用冒号分隔。字典使用花括号 {} 表示,例如:{'name': 'John', 'age': 30, 'city': 'New York'}。
集合(Set):集合是一种无序的、不重复的元素集合,主要用于去重和集合运算。集合使用花括号 {} 或 set() 函数来创建,例如:{1, 2, 3, 4} 或 set([1, 2, 3, 4])。
2 哪些是可变元素哪些不可变?
可变:列表、字典、集合。
不可变:数字类型(int、float)、boolean、字符串、元组。
3 为什么函数的参数不能传可变数据类型,举例说明?
在进行Python
函数参数传递时是引用传递。传递不可变类型对象时,改变形参的值,并不会改变实参的值;传递可变类型对象时,改变形参的值,也会改变实参的值。也就是如果传递的是可变类型,在函数内部对变量做了修改会影响实参。
a = 1
def fun(a):
a = 2
fun(a) # 不可变类型
print a # 1
a = []
def fun(b):
b.append(1)
fun(a) #可变类型
print a # [1]
4 什么是闭包?为什么使用闭包?闭包有什么优点有什么缺点?
函数执行后返回的结果是一个内部函数,并被外部变量所引用,如果内部函数持有被执行函数作用域的变量,则形成了闭包。
可以读取函数内部的变量。
优点:
- 创建变量的私有空间,防止变量污染全局。
- 内部函数可以访问外部函数作用域中的变量,且访问到的变量长期驻扎在内存中,可供以后使用。
缺点:
- 对内存消耗有负面影响。因内部函数保存了对外部变量的引用,导致无法被垃圾回收机制回收,增大了内存的使用量,所以使用不当会导致内存泄漏。
- 可能获取到意外的值。
- 对处理速度具有负面影响。闭包的层级决定了引用的外部变量在查找时经过的作用域链长度。
5 什么是生成器迭代器和可迭代对象?
生成器:()列表生成式和yield写的函数。
迭代器:可以被next()函数调用并不断返回下一个值的称之为迭代器。
可迭代对象:可以直接作用于 for 循环的对象统称为可迭代对象。
6 使用生成器生出斐波那契数列
def fib(n):
a, b = 0, 1
for i in range(0, n):
a, b = b, a + b
yield a
for i in fib(20):
print(i, end=' ') #输出前20位
7使用生成器生出杨辉三角形
def triangle_scq(n): # n:行数
triangle = [1] # 初始化杨辉三角
for i in range(n):
yield triangle
triangle = [1] + [triangle[j] + triangle[j - 1] for j in range(1, len(triangle))] + [1]
for i in triangle_scq(10): # 输出10行
print(i)
8 什么是魔术方法,举例说明你知道的魔术方法和具体作用?
魔术方法就是一个类的特殊方法,和普通方法唯一不同的是,普通方法需要调用,而魔术方法由系统自动调用。
__init__(self,): 初始化魔术方法
作用:初始化对象的成员。
__new__(cls,): 实例化魔术方法 类方法
作用:用于创建并返回一个新的实例。
返回值:必须返回一个对象实例。
9 说说什么是类方法,静态方法,类属性,实例属性,他们有什么区别?
类方法:使用@classmethod
装饰器进行修饰,第一个参数默认为cls
,表示类本身。类方法是可以被类和类的实例对象调用的。在类方法中不能访问实例属性和实例方法,因为它不依赖任何实例对象,而是依赖类本身,通常用于创建类对象或者对类属性的操作。
class MyClass:
x = 0
@classmethod
def classmethod(cls):
cls.x += 1
return cls.x
print(MyClass.classmethod()) # 输出1
print(MyClass.classmethod()) # 输出2
静态方法:使用@staticmethod
装饰器进行修饰,它不需要表示自身对象的self
和cls
参数。静态方法是类的工具包,它与类和实例对象没有任何关系,通常用于工具函数或类的初始化操作。
class MyClass:
@staticmethod
def staticmethod():
return "This is a static method."
print(MyClass.staticmethod()) # 输出"This is a static method."
类属性:是属于类对象的属性,它的值对于类的所有实例来说是相同的,类属性可以通过类名或实例名访问。
实例属性:是属于实例对象的属性,每个实例都可以有自己的属性值。实例属性只能通过实例名访问。
10 什么是单例模式?请你实现一个单例模式?
单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。
例子:
使用模块实现单例模式。在 Python 中,模块在导入时只会被执行一次,因此可以使用模块来实现单例模式。
# test.py
class SingleTon(object):
def __init__(self, name):
self.name = name
def run(self):
print(self.name)
s = SingleTon(name='vth')
# main.py
from test import s as s1
from test import s as s2
def show():
print(s1, id(s1))
print(s2, id(s2))
show()
11 说说三种高级方法的使用, map reduce filter
map():
映射,内置函数map()可以将一个函数依次映射到序列或迭代器对象的每个元素上,并返回一个可迭代的map对象作为结果,map对象中每个元素是原序列中元素经过该函数处理后的结果,该函数不对原序列或迭代器对象做任何修改。要注意,我们调用完map之后得到的结果不是一个list而是一个迭代器,我们想要获得完整的内容需要将它转化成list类型。
语法:map(function, iterable, …)
第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。
例子:
1.两个列表对相同位置的列表数据进行相加。
result = map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
print(list(result)) # [3, 7, 11, 15, 19]
2.单参数函数。
def add5(x):
return x+5
list(map(add5, range(10))) #把单参数函数映射到一个序列的所有元素 [5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
3.接收2个参数的函数。
def add(x, y):
return x+y
list(map(add, range(5), range(5,10))) #把双参数函数映射到两个序列上 [5, 7, 9, 11, 13]
list(map(lambda x, y: x+y, range(5), range(5,10))) # [5, 7, 9, 11, 13]
reduce() :
标准库functools中的函数reduce()可以将一个接收2个参数的函数以迭代累积的方式从左到右依次作用到一个序列或迭代器对象的所有元素上,并且允许指定一个初始值。
语法:reduce(function, iterable[, initializer])
函数将一个数据集合(链表,元组等)中的所有数据进行下列操作:用传给 reduce 中的函数 function(有两个参数)先对集合中的第 1、2 个元素进行操作,得到的结果再与第三个数据用 function 函数运算,最后得到一个结果。
例子:
计算列表中元素的和。
from functools import reduce
result = reduce(lambda x, y: x+y, [1,2,3,4,5])
print(result) # 15
result = reduce(lambda x, y: x + y, [[1], [2], [3], [4], [5]])
print(result) # [1, 2, 3, 4, 5]
filter():
它的用法和map有些类似,通过编写一个函数来判断元素是否合法。通过调用filter,会自动将这个函数应用到容器当中所有的元素上,最后只会保留运行结果是True的元素,而过滤掉那些是False的元素。
语法:filter(function, iterable)
该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回True 或 False,最后将返回 True 的元素放到新列表中。
例子:
{“a”,”ab”,”abc”,”bc”,”cd”}输出含有C字符的元素。
result = filter(lambda x: "c" in x, {"a", "ab", "abc", "bc", "cd"})
for n in result:
print(n) # abc cd bc
12 说说什么是装饰器,举个例子具体说明装饰器的作用
装饰器:外层函数返回里层函数的引用,里层函数引用外层函数的变量。
作用:装饰器的作用就是在不改变已有函数代码前提下,为该函数增加新的功能。
例子:
def w1(func):
"""装饰器函数"""
def inner():
func()
print("这是添加的新功能")
return inner
@w1 # 等同于调用函数的时候上方加上:f1 = w1(f1)
def f1():
"""业务函数"""
print("---f1---")
@w1 # 等同于调用函数的时候上方加上:f2 = w1(f2)
def f2():
"""业务器函数"""
print("---f2---")
f1() # ---f1---
# 这是添加的新功能
f2() # ---f2---
# 这是添加的新功能
13 说说什么是断言?有什么用?
断言就是断定指定条件一定成立,若不成立则抛出异常。
Python断言关键字为:assert,断言也可以理解为简单版的 if 语句,判断条件的值,若为True继续运行,否则停止运行并抛出AssertionError异常。
作用:
- 运行时检查代码逻辑
- 测试代码正确性
14 说如何读写文件,读文件写文件写二进制文件应该使用什么方法?
读文件
读取文本文件:
使用内置的 open
函数来打开文件并读取内容。
file_path = 'example.txt'
# 读取文件
with open(file_path, 'r') as file:
data = file.read()
print(data)
读取CSV文件:
使用 csv
模块来读取CSV格式的文件。
import csv
csv_file_path = 'example.csv'
# 读取CSV文件
with open(csv_file_path, 'r') as csvfile:
csv_reader = csv.reader(csvfile)
for row in csv_reader:
print(row)
读取JSON文件:
使用内置的 json
模块来读取JSON格式的文件。
import json
json_file_path = 'example.json'
# 读取JSON文件
with open(json_file_path, 'r') as jsonfile:
data = json.load(jsonfile)
print(data)
写入文件
写入文本文件:
使用内置的 open
函数来打开文件并写入内容。
file_path = 'example.txt'
# 写入文件
with open(file_path, 'w') as file:
file.write("Hello, this is some data.")
写入CSV文件:
使用 csv
模块来写入CSV格式的文件。
import csv
csv_file_path = 'example.csv'
data = [['Name', 'Age', 'Occupation'],
['John Doe', 30, 'Engineer'],
['Jane Smith', 25, 'Designer']]
with open(csv_file_path, 'w', newline='') as csvfile:
csv_writer = csv.writer(csvfile)
csv_writer.writerows(data)
写入JSON文件:
使用内置的 json
模块来写入JSON格式的文件。
import json
json_file_path = 'example.json'
data = {"name": "John Doe", "age": 30, "occupation": "Engineer"}
with open(json_file_path, 'w') as jsonfile:
json.dump(data, jsonfile)
模式表:
访问模式 | 说明 |
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a+ | 打开一个文件用于读写,如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果改文件不存在,创建新文件用于读写。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头 |
wb+ | 以二进制格式打开一个文件用于读写。如果改文件已存在则会覆盖。如果改文件不存在,创建新文件。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果改文件不存在,创建新文件用于读写。 |
15 如何读取大文件
读取文件时,如果文件过大,则一次读取全部内容到内存,容易造成内存不足,所以要对大文件进行批量的读取内容。先取一部分读取,然后释放内存;再取一部分读取,然后释放内存,往复循环直到读完。
16 写出冒泡排序
def bubble_sort(arr, n=None):
if n is None:
n = len(arr)
if n == 1:
return arr
for i in range(n-1):
if arr[i] > arr[i+1]:
arr[i], arr[i+1] = arr[i+1], arr[i]
bubble_sort(arr, n-1)
return arr
17 如何实现人工报错?
使用try-except 语句指定异常类型
用法:
try:
# 可能会发生异常的代码块
except 异常名称 :
# 处理异常类型的代码块(可以是提示性语句)
18 mysql 三表联查如何操作?写出伪代码?
SELECT * FROM table1
JOIN table2 ON table1.column = table2.column
JOIN table3 ON table2.column = table3.column;
19 如果现在已经知道有三个班级 A班 B班 C班,如何知道每个班级第二名的成绩?
20 说说python中的序列化反序列化以及具体作用?
序列化(Serialization):是指将数据结构或对象转换为可存储或传输的格式的过程。这通常涉及将数据转换为字节流或字符串,以便它们可以在不同的环境中传递或存储。
反序列化(Deserialization):是将序列化后的数据还原为原始数据结构或对象的过程。允许在接收端或将来的时间点重新使用数据。
作用:
- 数据交换:当不同的应用程序需要共享数据时,它们可能位于不同的计算机、操作系统或编程语言中。序列化数据使得跨越这些边界成为可能。
- 数据存储:序列化数据可以有效地保存在文件、数据库或其他持久性存储中,以备将来使用。
- 跨语言通信:如果系统需要与其他编程语言编写的组件进行通信,序列化和反序列化是一种跨语言通信的通用方式。
- 远程调用:在分布式系统中,远程调用需要将数据从客户端传输到服务器,并在服务器上执行操作。序列化和反序列化允许这种通信。