python面试题大全(一)

文件操作

1. 大文件读取问题

有一个jsonline格式的文件file.txt大小约为10K,如何读取内容?

#! -*-conding=: UTF-8 -*-
# 2024/1/19 16:46def get_lines():with open('file.txt', 'rb') as f:return f.readlines()if __name__ == '__main__':for line in get_lines():print(line)  # 处理每一行数据

现在要处理一个大小为10G的文件,但是内存只有4G,如果在只修改get_lines函数而其他代码保持不变的情况下,应该如何实现?需要考虑的问题都有那些?

#! -*-conding=: UTF-8 -*-
# 2024/1/19 16:46def get_lines():with open('file.txt', 'rb') as f:for i in f:yield iif __name__ == '__main__':for line in get_lines():print(line)  # 处理每一行数据

个人认为:还是设置下每次返回的内容较好,否则读取次数太多。

#! -*-conding=: UTF-8 -*-
# 2024/1/19 16:46def get_lines():with open('file.txt', 'r', encoding='utf-8') as f:_lines = []for line in f:_lines.append(line.strip())if len(_lines) == 2:yield _lines_lines = []if _lines:yield _linesif __name__ == '__main__':for lines in get_lines():print(lines)  # 处理每两行数据

使用itertools

import itertoolsdef get_lines(line):with open('file.txt', 'r', encoding='utf-8') as f:while True:_lines = list(itertools.islice(f, line))if len(_lines) < line:yield [line.strip() for line in _lines]breakyield [line.strip() for line in _lines]if __name__ == '__main__':for lines in get_lines(2):print(lines)  # 处理每两行数据

使用mmap库

from mmap import mmapdef get_lines(fp):with open(fp, "r+") as f:m = mmap(f.fileno(), 0)start = 0while True:pos = m.find(b"\n", start)if pos == -1:breakyield m[start:pos + 1].decode()start = pos + 1if __name__ == '__main__':for lines in get_lines('file.txt'):print(lines)  # 处理每两行数据

要考虑的问题有:

  • 内存只有4G无法一次性读入10G文件,需要分批读入分批读入数据要记录每次读入数据的位置。
  • 分批每次读取数据的大小,太小会在读取操作花费过多时间。

https://stackoverflow.com/questions/30294146/fastest-way-to-process-a-large-file

2. 目录遍历

请打印指定目录的目录树

#! -*-conding=: UTF-8 -*-
# 2024/1/19 16:46
import osdef print_directory_contents(s_path):"""这个函数接收文件夹的名称作为输入参数返回该文件夹中文件的路径以及其包含文件夹中文件的路径"""for s_child in os.listdir(s_path):s_child_path = os.path.join(s_path, s_child)if os.path.isdir(s_child_path):print_directory_contents(s_child_path)else:print(s_child_path)if __name__ == '__main__':print_directory_contents('.')

模块与包

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

#! -*-conding=: UTF-8 -*-
# 2024/1/19 16:46
import datetimedef day_of_year():year = input("请输入年份: ")month = input("请输入月份: ")day = input("请输入天: ")date1 = datetime.date(year=int(year), month=int(month), day=int(day))date2 = datetime.date(year=int(year), month=1, day=1)return (date1 - date2).days + 1if __name__ == '__main__':print(day_of_year())

4.打乱一个排好序的list对象alist?

import randomalist = [1, 2, 3, 4, 5]
random.shuffle(alist)
print(alist)

数据类型

5.现有字典 d= {‘a’:24,‘g’:52,‘i’:12,‘k’:33}请按value值进行排序?

d = {'a': 24, 'g': 52, 'i': 12, 'k': 33}# 升序
d_set = sorted(d.items(), key=lambda x: x[1], reverse=False)
print(d_set)  # [('i', 12), ('a', 24), ('k', 33), ('g', 52)]# 降序
print(sorted(d.items(), key=lambda x: x[1], reverse=True))
# [('g', 52), ('k', 33), ('a', 24), ('i', 12)]

x[0]代表用key进行排序;x[1]代表用value进行排序。

6.字典推导式

创建一个字典,将列表中的元素作为键,元素的平方作为值

my_list = [1, 2, 3, 4, 5]
my_dict = {x: x**2 for x in my_list}
print(my_dict)  # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

7.请反转字符串 “aStr”?

print("aStr"[::-1])  # rtSa

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

def process_string_to_dict(input_string):# 去除字符串中的空格input_string = input_string.replace(" ", "")# 拆分字符串成键值对列表pairs = input_string.split("|")# 创建字典my_dict = {}for pair in pairs:key, value = pair.split(":")my_dict[key] = int(value)return my_dict# 调用函数并打印结果
my_string = "k:1 |k1:2|k2:3|k3:4"
result_dict = process_string_to_dict(my_string)
print(result_dict)  # {'k': 1, 'k1': 2, 'k2': 3, 'k3': 4}# 字典推导式
print({k: int(v) for t in my_string.split("|") for k, v in (t.split(":"),)})
# {'k': 1, 'k1': 2, 'k2': 3, 'k3': 4}

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

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

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

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

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

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

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

list1 = [1, 2, 3]
list2 = [3, 4, 5]set1 = set(list1)
set2 = set(list2)print(set1 & set2)  # {3}
print(set1 ^ set2)  # {1, 2, 4, 5}

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

def duplicate_removal1(a):"""使用集合去重"""a = list(set(a))print(a)def duplicate_removal2(a):"""将一个列表的数据取出放到另一个列表中,中间作判断"""alist = []for i in a:if i not in alist:alist.append(i)# 如果需要排序的话用sortalist.sort()print(alist)def duplicate_removal3(a):"""使用字典"""b = {}b = b.fromkeys(a)c = list(b.keys())print(c)al = [1, 2, 4, 2, 4, 5, 7, 10, 5, 5, 7, 8, 9, 0, 3]
duplicate_removal1(a=al)  # [0, 1, 2, 3, 4, 5, 7, 8, 9, 10]
duplicate_removal2(a=al)  # [0, 1, 2, 3, 4, 5, 7, 8, 9, 10]
duplicate_removal3(a=al)  # [1, 2, 4, 5, 7, 10, 8, 9, 0, 3]

14.python如何实现单例模式?请写出两种实现方式?

  1. 使用装饰器实现单例模式:
import threadingdef singleton(cls):instances = {}lock = threading.Lock()def get_instance(*args, **kwargs):if cls not in instances:with lock:if cls not in instances:instances[cls] = cls(*args, **kwargs)return instances[cls]return get_instance@singleton
class IdGenerator:def __init__(self):self.id = 0def get_id(self):with threading.Lock():self.id += 1return self.idif __name__ == '__main__':singleton1 = IdGenerator()singleton2 = IdGenerator()print(singleton1 is singleton2)  # 输出 True,表示是同一个实例# 使用 __call__ 方法获取单例singleton3 = IdGenerator()print(singleton1 is singleton3)  # 输出 True,表示是同一个实例
import threadingclass SingletonDecorator:def __init__(self, cls):self._cls = clsself._instances = {}self._lock = threading.Lock()def __call__(self, *args, **kwargs):if self._cls not in self._instances:with self._lock:if self._cls not in self._instances:instance = self._cls(*args, **kwargs)self._instances[self._cls] = instancereturn self._instances[self._cls]@SingletonDecorator
class IdGenerator:def init_generator(self):self.id = 0def get_id(self):with threading.Lock():self.id += 1return self.idif __name__ == '__main__':singleton1 = IdGenerator()singleton2 = IdGenerator()print(singleton1 is singleton2)  # 输出 True,表示是同一个实例# 使用装饰器获取单例singleton3 = IdGenerator()print(singleton1 is singleton3)  # 输出 True,表示是同一个实例
  1. 通过__new__方法实现单例
#! -*-conding=: UTF-8 -*-
# 2023/9/13 18:21import threadingclass LazySingleton:_instance = None_lock = threading.Lock()def __new__(cls, *args, **kwargs):with cls._lock:if cls._instance is None:cls._instance = super(LazySingleton, cls).__new__(cls, *args, **kwargs)cls._instance.init_generator()return cls._instancedef init_generator(self):self.id = 0def get_id(self):with self._lock:self.id += 1return self.id# 使用示例
singleton1 = LazySingleton()
singleton2 = LazySingleton()print(singleton1 is singleton2)  # 输出 True,表示是同一个实例
  1. 使用类方法实现单例
import threadingclass IdGenerator:_instance = None_lock = threading.Lock()def __init__(self):self.init_generator()def init_generator(self):self.id = 0def get_id(self):with self._lock:self.id += 1return self.id@classmethoddef get_instance(cls):if cls._instance is None:with cls._lock:if cls._instance is None:cls._instance = cls()return cls._instanceif __name__ == '__main__':singleton1 = IdGenerator.get_instance()singleton2 = IdGenerator.get_instance()print(singleton1 is singleton2)  # 输出 True,表示是同一个实例
  1. 使用元类metaclass实现单例模式
import threadingclass SingletonMeta(type):_instances = {}_lock = threading.Lock()def __call__(cls, *args, **kwargs):if cls not in cls._instances:with cls._lock:if cls not in cls._instances:instance = super(SingletonMeta, cls).__call__(*args, **kwargs)cls._instances[cls] = instancereturn cls._instances[cls]class IdGenerator(metaclass=SingletonMeta):def init_generator(self):self.id = 0def get_id(self):with threading.Lock():self.id += 1return self.idif __name__ == '__main__':singleton1 = IdGenerator()singleton2 = IdGenerator()print(singleton1 is singleton2)  # 输出 True,表示是同一个实例

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

要反转一个整数,可以使用数学运算和字符串操作来实现。

def reverse_integer(n):# 将整数转换为字符串num_str = str(n)# 判断是否有负号if num_str[0] == '-':# 如果有负号,保留负号并反转剩余部分reversed_str = '-' + num_str[:0:-1]else:# 如果没有负号,直接反转整个字符串reversed_str = num_str[::-1]# 将反转后的字符串转换为整数_reversed_num = int(reversed_str)return _reversed_num# 测试
num = -123
reversed_num = reverse_integer(num)
print(reversed_num)  # -321

16.设计实现遍历目录与子目录,抓取.pyc文件

第一种方法

import osdef get_files(_dir, suffix):res = []for root, dirs, files in os.walk(_dir):for filename in files:name, suf = os.path.splitext(filename)if suf == suffix:res.append(os.path.join(root, filename))print(res)get_files("./", '.pyc')

第二种方法

import osdef pick(obj):if obj.endswith(".pyc"):print(obj)def scan_path(ph):file_list = os.listdir(ph)for obj in file_list:if os.path.isfile(obj):pick(obj)elif os.path.isdir(obj):scan_path(obj)if __name__ == '__main__':scan_path("./")

17.一行代码实现1-100之和

print(sum(range(0, 101)))

18.遍历列表时删除元素的正确做法

复制一份列表操作

a = [1, 2, 3, 4, 5, 6, 7, 8]
print(id(a))
print(id(a[:]))
for i in a[:]:if i > 5:passelse:a.remove(i)
print(a)

使用倒序遍历
在循环过程中,从列表末尾开始倒序遍历,然后使用 del 语句删除需要删除的元素。这样做可以避免由于删除元素而导致的索引错位或跳过元素的问题。

my_list = [1, 2, 3, 4, 5]for i in range(len(my_list) - 1, -1, -1):if my_list[i] > 3:del my_list[i]print(my_list)  # [1, 2, 3]

创建新列表

my_list = [1, 2, 3, 4, 5]
new_list = []for item in my_list:if item > 3:new_list.append(item)print(new_list)  # [4, 5]

18.字符串操作

全字母短句 PANGRAM 是包含所有英文字母的句子,比如:A QUICK BROWN FOX JUMPS OVER THE LAZY DOG

定义并实现一个方法get_missing_letter, 传入一个字符串采纳数,返回参数字符串变成一个PANGRAM中所缺失的字符。应该忽略传入字符串参数中的大小写,返回应该都是小写字符并按字母顺序排序(请忽略所有非 ACSII 字符)。

下面示例是用来解释,双引号不需要考虑:

下面示例是用来解释,双引号不需要考虑:
输入: "A quick brown for jumps over the lazy dog"
返回: ""输入: "A slow yellow fox crawls under the proactive dog"
返回: "bjkmqz"输入: "Lions, and tigers, and bears, oh my!"
返回: "cfjkpquvwxz" 输入: ""
返回:"abcdefghijklmnopqrstuvwxyz"

使用set求解

import stringprint(string.ascii_lowercase)  # abcdefghijklmnopqrstuvwxyzprint("".join(map(chr, range(ord('a'), ord('z') + 1))))  # abcdefghijklmnopqrstuvwxyzdef get_missing_letter(a):s1 = set(string.ascii_lowercase)s2 = set(a.lower())ret = "".join(sorted(s1 - s2))return retprint(get_missing_letter("xyz"))  # abcdefghijklmnopqrstuvw

19. 可变类型和不可变类型

1,可变类型有list,dict.不可变类型有string,number,tuple.

2,当进行修改操作时,可变类型传递的是内存中的地址,也就是说,直接修改内存中的值,并没有开辟新的内存。

3,不可变类型被改变时,并没有改变原内存地址中的值,而是开辟一块新的内存,将原地址中的值复制过去,对这块新开辟的内存中的值进行操作。

20. is和==有什么区别?

  • is:比较的是两个对象的id值是否相等,也就是比较俩对象是否为同一个实例对象。是否指向同一个内存地址
  • == : 比较的两个对象的内容/值是否相等,默认会调用对象的eq()方法

21. 求出列表所有奇数并构造新列表

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

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

from functools import reduce# 1.使用sum内置求和函数
num = sum([1, 2, 3, 10248])
print(num)
# 2.reduce 函数
num1 = reduce(lambda x, y: x + y, [1, 2, 3, 10248])
print(num1)

23. 字符串 “123” 转换成 123 ,不使用内置api,例如int()

方法一:利用 str 函数

def atoi(s):num = 0for v in s:for j in range(10):if v == str(j):num = num * 10 + jreturn numprint(atoi("123"))  # 123

方法二:利用 ord 函数

def atoi(s):num = 0for v in s:num = num * 10 + ord(v) - ord('0')return numprint(atoi("123"))  # 123

方法三: 利用 eval 函数

def atoi(s):num = 0for v in s:t = "%s * 1" % vn = eval(t)num = num * 10 + nreturn numprint(atoi("123"))  # 123

方法四: 结合方法二,使用 reduce ,一行解决

from functools import reducedef atoi(s):return reduce(lambda num, v: num * 10 + ord(v) - ord('0'), s, 0)print(atoi("123"))  # 123

24. 两数和

给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用

示例:

给定nums = [2,7,11,15],target=9;因为 nums[0]+nums[1] = 2+7 =9,所以返回[0,1]。

class Solution:@staticmethoddef two_sum(nums, target):""":type nums: List[int]:type target: int:rtype: List[int]"""d = {}size = 0while size < len(nums):if target - nums[size] in d:if d[target - nums[size]] < size:return [d[target - nums[size]], size]else:d[nums[size]] = sizesize = size + 1solution = Solution()print(solution.two_sum(nums=[2, 7, 11, 15], target=18))  # [1, 2]

方法二:

class Solution(object):@staticmethoddef two_sum(nums, target):for i in range(len(nums)):num = target - nums[i]if num in nums[i + 1:]:return [i, nums.index(num, i + 1)]solution = Solution()print(solution.two_sum(nums=[2, 7, 11, 15], target=18))  # [1, 2]

25. 统计一个文本中单词频次最高的10个单词?

import redef test(filepath):distone = {}with open(filepath) as f:for line in f:line = re.sub("\W+", " ", line)lineone = line.split()for keyone in lineone:if not distone.get(keyone):distone[keyone] = 1else:distone[keyone] += 1num_ten = sorted(distone.items(), key=lambda x: x[1], reverse=True)[:10]print(num_ten)  # [('aaaa', 1), ('dsds', 1), ('sdsdsds', 1)]num_ten = [x[0] for x in num_ten]return num_tenprint(test("./file.txt"))  # ['aaaa', 'dsds', 'sdsdsds']

方法二:

import re
from collections import Counterdef test2(filepath):with open(filepath) as f:return list(map(lambda c: (c[0], c[1]), Counter(re.sub("\W+", " ", f.read()).split()).most_common(10)))print(test2("./file.txt"))

26. 请写出一个函数满足以下条件

该函数的输入是一个仅包含数字的list,输出一个新的list,其中每一个元素要满足以下条件:

  • 1、该元素是偶数
  • 2、该元素在原list中是在偶数的位置(index是偶数)
def num_list(num):return [i for i in num if i % 2 == 0 and num.index(i) % 2 == 0]result = num_list(num=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(result)  # [0, 2, 4, 6, 8, 10]

27. 使用单一的列表生成式来产生一个新的列表

该列表只包含满足以下条件的值,元素为原始列表中偶数切片:

list_data = [1, 2, 5, 8, 10, 3, 18, 6, 20]
res = [x for x in list_data[::2] if x % 2 == 0]
print(res)  # [10, 18, 20]

28. 用一行代码生成[1,4,9,16,25,36,49,64,81,100]

result = [x * x for x in range(1, 11)]

29. 两个有序列表,l1,l2,对这两个列表进行合并不可使用extend

方法一:

merged_list = sorted(l1 + l2)

方法二:使用循环

def loop_merge_sort(l1, l2):tmp = []while len(l1) > 0 and len(l2) > 0:if l1[0] < l2[0]:tmp.append(l1[0])del l1[0]else:tmp.append(l2[0])del l2[0]while len(l1) > 0:tmp.append(l1[0])del l1[0]while len(l2) > 0:tmp.append(l2[0])del l2[0]return tmpl1 = [1, 3, 5, 7]
l2 = [2, 4, 6, 8, 9]
result = loop_merge_sort(l1, l2)
print(result)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

30. 让所有奇数都在偶数前面,而且奇数升序排列,偶数降序排序

方法一:

def func1(l):if isinstance(l, str):l = [int(i) for i in l]if isinstance(l, list):l.sort(reverse=True)for i in range(len(l)):if l[i] % 2 > 0:l.insert(0, l.pop(i))print(''.join(str(e) for e in l))l1 = [3, 5, 2, 7, 1, 4]
func1(l1)  # 135742l2 = "568731"
func1(l2)  # 135786

方法二:

def func2(l):if isinstance(l, str):l = list(l)l = sorted(l, key=lambda x: int(x) % 2 == 0 and 20 - int(x) or int(x))print("".join(str(e) for e in l))l1 = [3, 5, 2, 7, 1, 4]
func2(l1)  # 135742l2 = "568731"
func2(l2)  # 135786

31. 写一个函数找出一个整数数组中,第二大的数

def find_second_large_num(num_list):# 方法一:直接排序,输出倒数第二个数即可tmp_list = sorted(num_list)print("方法一\nSecond_large_num is:", tmp_list[-2])# 方法二:设置两个标志位,一个存储最大数,一个存储次大数one = num_list[0]two = num_list[0]for i in range(1, len(num_list)):if num_list[i] > one:two = oneone = num_list[i]elif num_list[i] > two:two = num_list[i]print("方法二\nSecond_large_num is:", two)# 方法三:使用 reduce 与逻辑符号 (and, or)# 基本思路与方法二一样,但是不需要用 if 进行判断。from functools import reducenum = reduce(lambda ot, x: ot[1] < x and (ot[1], x) or ot[0] < x and (x, ot[1]) or ot, num_list, (0, 0))[0]print("方法三\nSecond_large_num is:", num)num_list = [34, 11, 23, 56, 78, 0, 9, 12, 3, 7, 5]
find_second_large_num(num_list)"""
方法一
Second_large_num is: 56
方法二
Second_large_num is: 56
方法三
Second_large_num is: 56
"""

32. 阅读一下代码他们的输出结果是什么?

def multi():return [lambda x: i * x for i in range(4)]print([m(3) for m in multi()])  # [9, 9, 9, 9]

这段代码创建了一个包含四个 lambda 函数的列表,并尝试通过列表推导式对这些 lambda 函数进行调用。然而,由于在 lambda 函数中使用了变量 i,而 i 是在循环结束后的值,这导致 lambda 函数在被调用时都引用了相同的最终值。

因此,代码的输出结果将是 [9, 9, 9, 9],而不是 [0, 3, 6, 9]

这是因为在循环结束后,变量 i 的值为 3,而所有的 lambda 函数都引用了这个最终值。所以,当你调用这些 lambda 函数时,它们实际上是使用值为 3 的 i 来计算结果。

如果你想要得到 [0, 3, 6, 9] 的输出结果,可以在 lambda 函数中使用默认参数来捕获循环变量 i 的值。以下是修改后的代码:

def multi():return [lambda x, i=i: i * x for i in range(4)]print([m(3) for m in multi()])

通过在 lambda 函数定义中添加 i=i,我们在创建 lambda 函数时捕获了循环变量 i 的当前值,并将其作为默认参数。这样,在每次调用 lambda 函数时,它将使用捕获的默认参数值来计算结果,而不是引用最终值。

这样修改后的代码将输出 [0, 3, 6, 9],符合预期的结果。

33. 统计一段字符串中字符出现的次数

方法一:

def count_str(str_data):"""定义一个字符出现次数的函数"""dict_str = {}for i in str_data:dict_str[i] = dict_str.get(i, 0) + 1return dict_strdict_str = count_str("AAABBCCAC")
str_count_data = ""for k, v in dict_str.items():str_count_data += k + str(v)
print(dict_str)  # {'A': 4, 'B': 2, 'C': 3}
print(str_count_data)  # A4B2C3

方法二:

from collections import Counterprint(list(map(lambda x: (x[0], x[1]), Counter("AAABBCCAC").most_common())))  # [('A', 4), ('C', 3), ('B', 2)]

34. super函数的具体用法和场景

在Python中,super()函数用于调用父类的方法。它主要用于子类重写父类方法时,在子类中调用父类的相同方法,以实现方法的继承和扩展。

super()函数的常见用法是在子类的方法中调用父类的同名方法。通过使用super()函数,子类可以直接调用父类的方法,并在该方法的基础上进行扩展。这种方式可以保持代码的重用性和结构的一致性。

super()函数的语法如下:

super().父类方法名(参数列表)

在使用super()函数时,不需要显式地指定父类的名称,Python会自动根据当前类的继承关系来确定要调用的父类方法。

下面是一个简单的示例,演示了super()函数的用法:

class ParentClass:def __init__(self):self.parent_attr = "Parent Attribute"def some_method(self):print("Parent Method")class ChildClass(ParentClass):def __init__(self):super().__init__()  # 调用父类的 __init__ 方法self.child_attr = "Child Attribute"def some_method(self):super().some_method()  # 调用父类的 some_method 方法print("Child Method")child = ChildClass()
print(child.parent_attr)  # 输出: Parent Attribute
print(child.child_attr)  # 输出: Child Attribute
child.some_method()  # 输出: Parent Method#      Child Method

在上面的示例中,ChildClass继承自ParentClass。子类ChildClass中的构造函数__init__使用super()函数调用了父类ParentClass的构造函数,以便子类能够继承父类的属性。另外,子类ChildClass重写了父类的some_method方法,并在方法中通过super()函数调用了父类的同名方法,以实现方法的扩展。

总结来说,super()函数在子类中调用父类方法的场景包括但不限于以下情况:

  1. 子类需要继承父类的属性或方法。
  2. 子类需要在重写父类方法时,在子类方法中调用父类的同名方法以实现方法的继承和扩展。
  3. 子类需要在多重继承的情况下,调用指定父类的方法。

35. Python中类方法、类实例方法、静态方法有何区别?

在Python中,类方法(class method)、类实例方法(instance method)和静态方法(static method)是三种不同类型的方法,它们在使用方式和功能上有一些区别。

  1. 类方法(Class Method):

    • 使用@classmethod装饰器进行修饰。
    • 第一个参数为类本身,通常被命名为cls
    • 类方法可以通过类或实例进行调用。
    • 类方法可以访问类属性,并且可以修改类属性的值。
    • 类方法常用于对类属性进行操作、创建类的备用构造函数等。
  2. 类实例方法(Instance Method):

    • 在类中定义的普通方法,默认为实例方法。
    • 第一个参数为实例对象本身,通常被命名为self
    • 实例方法只能通过类的实例进行调用。
    • 实例方法可以访问和修改实例属性和类属性。
    • 实例方法常用于操作和访问实例的状态和属性。
  3. 静态方法(Static Method):

    • 使用@staticmethod装饰器进行修饰。
    • 静态方法不需要传递类或实例作为参数。
    • 静态方法可以通过类或实例进行调用,但不会自动传递类或实例参数。
    • 静态方法不能访问或修改实例属性和类属性。
    • 静态方法通常用于与类相关的功能,但不依赖于实例状态或属性的操作。

下面是一个示例,演示了类方法、类实例方法和静态方法的使用:

class MyClass:class_attr = "Class Attribute"@classmethoddef class_method(cls):print("This is a class method")print("Accessing class attribute:", cls.class_attr)def instance_method(self):print("This is an instance method")print("Accessing class attribute:", self.class_attr)print("Accessing instance attribute:", self.instance_attr)@staticmethoddef static_method():print("This is a static method")# 调用类方法
MyClass.class_method()  # 输出: This is a class method#      Accessing class attribute: Class Attribute# 创建实例对象
my_obj = MyClass()
my_obj.instance_attr = "Instance Attribute"# 调用实例方法
my_obj.instance_method()  # 输出: This is an instance method#      Accessing class attribute: Class Attribute#      Accessing instance attribute: Instance Attribute# 调用静态方法
MyClass.static_method()  # 输出: This is a static method

总结:

  • 类方法使用@classmethod修饰,第一个参数为cls,可以通过类或实例调用,可以访问和修改类属性。
  • 类实例方法是普通的实例方法,默认以self作为第一个参数,只能通过实例调用,可以访问和修改实例属性和类属性。
  • 静态方法使用@staticmethod修饰,不需要类或实例作为参数,可以通过类或实例调用,但不能访问或修改实例属性和类属性。

36. 遍历一个object的所有属性,并print每一个属性名?

要遍历一个对象的所有属性并打印每个属性名,你可以使用内置的dir()函数获取对象的所有属性名称列表。然后,你可以使用getattr()函数获取每个属性的值,并打印属性名。

下面是一个示例代码,展示了如何遍历对象的所有属性并打印属性名:

class MyClass:def __init__(self):self.attribute1 = "Value 1"self.attribute2 = "Value 2"self.attribute3 = "Value 3"my_obj = MyClass()# 获取对象的属性列表
attribute_list = dir(my_obj)# 遍历属性列表并打印属性名
for attribute_name in attribute_list:attribute_value = getattr(my_obj, attribute_name)print(attribute_name)

在上面的示例中,我们定义了一个名为MyClass的类,并创建了一个my_obj的实例。然后,我们使用dir()函数获取my_obj的所有属性名称列表,并将其存储在attribute_list中。接下来,我们使用for循环遍历attribute_list,对于每个属性名attribute_name,我们使用getattr()函数获取该属性的值,并打印属性名。

请注意,dir()函数返回的属性列表包括对象的所有属性,包括类定义的属性、继承的属性和一些内置属性。因此,遍历属性时可能会包含一些你不感兴趣的属性。你可以根据自己的需求进行过滤或处理。

37.写一个类,并让它尽可能多的支持操作符?

自定义int类

class MyNumber:def __init__(self, value):self.value = valuedef __add__(self, other):if isinstance(other, MyNumber):return MyNumber(self.value + other.value)elif isinstance(other, int):return MyNumber(self.value + other)else:raise TypeError("Unsupported operand type for +")def __sub__(self, other):if isinstance(other, MyNumber):return MyNumber(self.value - other.value)elif isinstance(other, int):return MyNumber(self.value - other)else:raise TypeError("Unsupported operand type for -")def __mul__(self, other):if isinstance(other, MyNumber):return MyNumber(self.value * other.value)elif isinstance(other, int):return MyNumber(self.value * other)else:raise TypeError("Unsupported operand type for *")def __str__(self):return str(self.value)def __eq__(self, other):if isinstance(other, MyNumber):return self.value == other.valueelif isinstance(other, int):return self.value == otherelse:raise TypeError("Unsupported operand type for ==")def __lt__(self, other):if isinstance(other, MyNumber):return self.value < other.valueelif isinstance(other, int):return self.value < otherelse:raise TypeError("Unsupported operand type for <")# 创建 MyNumber 对象
num1 = MyNumber(5)
num2 = MyNumber(3)# 加法
result_add = num1 + num2
print(result_add)  # 输出: 8# 减法
result_sub = num1 - num2
print(result_sub)  # 输出: 2# 乘法
result_mul = num1 * num2
print(result_mul)  # 输出: 15# 字符串表示
print(str(num1))  # 输出: 5# 相等性比较
print(num1 == num2)  # 输出: False# 小于比较
print(num1 < num2)  # 输出: False

自定义list类

class MyList:def __init__(self):self.items = []def __del__(self):del self.itemsdef __str__(self):return str(self.items)def __add__(self, other):if isinstance(other, MyList):new_list = MyList()new_list.items = self.items + other.itemsreturn new_listelse:raise TypeError("Unsupported operand type for +")def __sub__(self, other):if isinstance(other, MyList):new_list = MyList()new_list.items = [item for item in self.items if item not in other.items]return new_listelse:raise TypeError("Unsupported operand type for -")def __mul__(self, other):if isinstance(other, int):new_list = MyList()new_list.items = self.items * otherreturn new_listelse:raise TypeError("Unsupported operand type for *")def __eq__(self, other):if isinstance(other, MyList):return self.items == other.itemselse:return Falsedef __lt__(self, other):if isinstance(other, MyList):return len(self.items) < len(other.items)else:raise TypeError("Unsupported operand type for <")def __getitem__(self, index):return self.items[index]def __len__(self):return len(self.items)def remove(self, item):self.items.remove(item)def display_items(self):for item in self.items:print(item)# 创建 MyList 对象
my_list1 = MyList()
my_list2 = MyList()# 添加元素
my_list1.items.append('Apple')
my_list1.items.append('Banana')
my_list1.items.append('Orange')my_list2.items.append('Apple')
my_list2.items.append('Grapes')# 加法
result_add = my_list1 + my_list2
print(result_add)  # 输出: ['Apple', 'Banana', 'Orange', 'Apple', 'Grapes']# 减法
result_sub = my_list1 - my_list2
print(result_sub)  # 输出: ['Banana', 'Orange']# 乘法
result_mul = my_list1 * 2
print(result_mul)  # 输出: ['Apple', 'Banana', 'Orange', 'Apple', 'Banana', 'Orange']# 字符串表示
print(str(my_list1))  # 输出: ['Apple', 'Banana', 'Orange']# 相等性比较
print(my_list1 == my_list2)  # 输出: False# 小于比较
print(my_list1 < my_list2)  # 输出: False# 获取元素
print(my_list1[1])  # 输出: Banana# 删除元素
my_list1.remove('Banana')
print(my_list1)  # 输出: ['Apple', 'Orange']# 显示所有元素
my_list1.display_items()
# 输出:
# Apple
# Orange# 获取列表长度
print(len(my_list1))  # 输出: 2# 删除 MyList 对象
del my_list1

38. 介绍Cython,Pypy Cpython Numba各有什么优缺点?

Cython、PyPy、CPython和Numba是针对Python代码进行优化的工具和实现方式。它们各自具有不同的优点和缺点,下面是对它们的简要介绍:

  1. Cython:

    • 优点:
      • 提供了静态类型声明和编译扩展的能力,可以将Python代码转换为C语言并编译成高效的机器码。
      • 可以直接调用C/C++代码,并且与Python语法兼容。
      • 支持使用Python标准库和第三方库。
      • 可以获得接近C语言的性能。
    • 缺点:
      • 编写和调试Cython代码可能相对复杂,需要对C语言有一定的了解。
      • 需要编译过程,增加了开发和部署的复杂性。
  2. PyPy:

    • 优点:
      • 使用即时编译(Just-in-Time Compilation)技术,可以在运行时动态地将Python代码转换为机器码,提高执行速度。
      • 支持大部分Python语法和标准库。
      • 对于某些特定类型的Python代码,PyPy的性能可能比CPython更好。
    • 缺点:
      • PyPy并不是完全兼容CPython,有些第三方库可能无法正常工作。
      • 在某些情况下,PyPy的内存占用可能比CPython更高。
      • 对于某些特定类型的Python代码,PyPy的性能可能比CPython差。
  3. CPython:

    • 优点:
      • 官方和最常用的Python解释器。
      • 拥有广泛的第三方库和生态系统支持。
      • 可以与C扩展无缝集成。
      • 相对稳定,支持性良好。
    • 缺点:
      • 在某些情况下,CPython的执行速度可能较慢。
      • 由于全局解释器锁(Global Interpreter Lock,GIL)的存在,无法充分利用多核处理器。
  4. Numba:

    • 优点:
      • 使用即时编译技术,可以将Python代码转换为高效的机器码。
      • 通过提供装饰器和函数修饰符,可以轻松地将Python函数转换为高性能的机器码。
      • 相对于使用NumPy进行数值计算,Numba可以提供更快的执行速度。
    • 缺点:
      • 对于某些类型的Python代码,Numba的性能优势可能不明显。
      • 不支持所有的Python语法和标准库。
      • 对于大型、复杂的代码,Numba的编译时间可能较长。

需要注意的是,每种工具和实现方式都有其适用的场景。选择合适的工具取决于你的具体需求,如性能要求、代码复杂性、对第三方库的依赖等因素。在实际使用时,可以根据具体情况进行评估和测试,以选择最适合的工具和实现方式。

39. 请描述python中抽象类和接口类的区别和联系?

  • 1.抽象类: 规定了一系列的方法,并规定了必须由继承类实现的方法。由于有抽象方法的存在,所以抽象类不能实例化。可以将抽象类理解为毛坯房,门窗,墙面的样式由你自己来定,所以抽象类与作为基 类的普通类的区别在于约束性更强。

  • 2.接口类:与抽象类很相似,表现在接口中定义的方法,必须由引用类实现,但他与抽象类的根本区别在于用途:与不同个体间沟通的规则,你要进宿舍需要有钥匙,这个钥匙就是你与宿舍的接口,你的舍 友也有这个接口,所以他也能进入宿舍,你用手机通话,那么手机就是你与他人交流的接口。

  • 3.区别和关联:

    • 1.接口是抽象类的变体,接口中所有的方法都是抽象的,而抽象类中可以有非抽象方法,抽象类是声明 方法的存在而不去实现它的类
    • 2.接口可以继承,抽象类不行
    • 3.接口定义方法,没有实现的代码,而抽象类可以实现部分方法
    • 4.接口中基本数据类型为static而抽象类不是

举个栗子:

首先,我们使用抽象类来表示一个动物,并定义一个抽象方法 make_sound,表示动物发出声音的行为。

from abc import ABC, abstractmethodclass Animal(ABC):@abstractmethoddef make_sound(self):pass

接下来,我们定义两个具体的动物类:狗和猫,它们都继承自抽象类 Animal,并实现了 make_sound 方法。

class Dog(Animal):def make_sound(self):print("Dog barks")class Cat(Animal):def make_sound(self):print("Cat meows")

现在,我们可以创建 DogCat 的实例,并调用它们的 make_sound 方法。

dog = Dog()
dog.make_sound()  # 输出: Dog barkscat = Cat()
cat.make_sound()  # 输出: Cat meows

在这个例子中,Animal 是一个抽象类,它定义了一个抽象方法 make_soundDogCat 是具体的动物类,它们继承了抽象类 Animal 并实现了 make_sound 方法。通过这种方式,我们可以使用抽象类 Animal 来表示一类动物,并要求每个具体的动物类都必须实现 make_sound 方法。

接下来,我们使用接口类来定义一个 Runnable 接口,表示可运行的对象,并定义一个抽象方法 run,表示对象运行的行为。

class Runnable:@abstractmethoddef run(self):pass

然后,我们定义一个具体的类 Car,它实现了 Runnable 接口,并实现了 run 方法。

class Car(Runnable):def run(self):print("Car is running")

现在,我们可以创建 Car 的实例,并调用它的 run 方法。

car = Car()
car.run()  # 输出: Car is running

在这个例子中,Runnable 是一个接口类(在Python中没有明确的语法支持),它定义了一个抽象方法 runCar 是一个具体的类,它实现了 Runnable 接口并提供了 run 方法的具体实现。通过这种方式,我们可以使用接口类 Runnable 来表示一类可运行的对象,并要求每个具体的类都必须实现 run 方法。

这就是一个简单的例子,展示了如何使用抽象类和接口类来表示抽象概念并要求子类提供具体的实现。抽象类和接口类在软件设计中起到了规范和约束的作用,帮助我们构建可扩展、灵活的代码架构。

40. Python中如何动态获取和设置对象的属性?

在Python中,可以使用以下方式动态获取和设置对象的属性:

  1. 获取属性

    • 使用点号运算符(.):通过对象的名称和属性名称,可以使用点号运算符直接访问对象的属性。
    obj.attribute  # 获取对象obj的attribute属性的值
    
    • 使用getattr()函数:getattr()函数可以接收一个对象和属性名称作为参数,并返回对象的属性值。如果属性不存在,可以提供一个默认值作为第三个参数。
    getattr(obj, 'attribute')  # 获取对象obj的attribute属性的值
    
  2. 设置属性

    • 使用点号运算符(.):通过对象的名称和属性名称,可以使用点号运算符直接设置对象的属性值。
    obj.attribute = value  # 设置对象obj的attribute属性的值为value
    
    • 使用setattr()函数:setattr()函数可以接收一个对象、属性名称和属性值作为参数,并将对象的属性设置为指定的值。
    setattr(obj, 'attribute', value)  # 设置对象obj的attribute属性的值为value
    

需要注意的是,使用动态获取和设置属性的方式可以方便地在运行时根据需要访问和修改对象的属性。但是,如果属性不存在,直接使用点号运算符会引发AttributeError异常;而使用getattr()函数可以通过提供默认值来避免异常的抛出。类似地,如果设置属性时,使用点号运算符设置一个不存在的属性会创建一个新的属性,而使用setattr()函数可以更严格地控制属性的设置行为。

另外,还可以使用hasattr()函数来检查对象是否具有特定的属性,以及使用delattr()函数来删除对象的属性。这些函数提供了更多操作对象属性的灵活性和控制性。

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

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

相关文章

如何在CentOS8使用宝塔面板本地部署Typecho个人网站并实现公网访问【内网穿透】

文章目录 前言1. 安装环境2. 下载Typecho3. 创建站点4. 访问Typecho5. 安装cpolar6. 远程访问Typecho7. 固定远程访问地址8. 配置typecho 前言 Typecho是由type和echo两个词合成的&#xff0c;来自于开发团队的头脑风暴。Typecho基于PHP5开发&#xff0c;支持多种数据库&#…

重拾计网-第四弹 计算机网络性能指标

ps&#xff1a;本文章的图片内容来源都是来自于湖科大教书匠的视频&#xff0c;声明&#xff1a;仅供自己复习&#xff0c;里面加上了自己的理解 这里附上视频链接地址&#xff1a;1.5 计算机网络的性能指标&#xff08;1&#xff09;_哔哩哔哩_bilibili ​​​ 目录 &#x…

有意思的问题

一个教授、一个助教、一个数字设计专业的学生和一个新生需要在黑夜里经过一座摇摇晃晃的桥。这座桥很不稳固&#xff0c;每次只能有两个人通过。他们只有一把火炬&#xff0c;而且桥的跨度太大无法把火炬扔回来&#xff0c;因此必须有人要把火炬拿回来。新生过桥需要1分钟&…

#Uniapp:引入fonts目录结构全局样式启动模式全局变量

uni-app 运行到微信开发者工具需要注意 小程序路径需要配置&#xff0c;小程序端口需要开启 目录结构 pages // 存放页面static // 静态资源uni_modules // 文件夹&#xff1a;用于存放 uniapp 项目的各种依赖文件。unpackage // 打包文件目录App.vue // 根组件main.js //…

最全笔记软件盘点!你要的笔记神器都在这里:手写笔记、知识管理、文本笔记、协作笔记等!

在当今的信息化社会中&#xff0c;人们对信息的处理速度越来越快&#xff0c;从工作到生活&#xff0c;我们都面临着大量信息的冲击。在这样的环境下&#xff0c;一个能够帮助我们管理、整理和储存信息的好工具显得尤为重要&#xff0c;而笔记软件恰恰可以满足这些需求。 在选…

工作小计- RGB相关算子实现

项目中的模型一直都是直接操作NV12的yuv格式数据&#xff0c;这次的模型只支持RGB格式的输入&#xff0c;正好来自己实现对应的算子。 这里记录一下对应算子的实现过程&#xff0c;主要涉及到NV12到RGB的变换&#xff0c;RGB的crop/resize操作&#xff0c;对于数据的Norm/ToFlo…

P1068 [NOIP2009 普及组] 分数线划定————C++、Python

目录 [NOIP2009 普及组] 分数线划定题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 解题思路C CodePython Code运行结果 [NOIP2009 普及组] 分数线划定 题目描述 世博会志愿者的选拔工作正在 A 市如火如荼的进行。为了选拔最合适的人才&#xff0c;A 市对所有报…

Jira REST API_获取创建issue时的字段配置

文章目录 背景解决方案获取创建项目的问题类型&#xff1a;获取指定问题类型创建时的字段配置可以通过参数扩展获取指定项目、类型的创建界面字段信息 背景 通过 Jira REST API 创建 jira issue 时&#xff0c;可以根据jira 配置&#xff0c;动态获取需要填写的字段&#xff1…

常用芯片学习——HC573芯片

HC573 三态输出八路透明 D 类锁存器 使用说明 锁存器是一种对脉冲电平敏感的存储单元电路&#xff0c;它们可以在特定输入脉冲电平作用下改变状态。锁存&#xff0c;就是把信号暂存以维持某种电平状态。锁存器的最主要作用是缓存&#xff0c;其次完成高速的控制器与慢速的外设…

学习C语言的第26天

字符串出现次数 #include<stdio.h> char* my_strstr(char*str1,char*str2) {char*fstr1;//遍历原字符串指针char*rstr1;//记录每次字符串首地址char*tstr2;while(*str1){rf;while(*f*t&&*f !\0){f;t;}if(*t \0){return r;} //回滚fr;tstr2;f;}return NULL;}#inc…

phpyun 7.0补丁升级后由于缓存极致bug造成“网络招聘会”栏目不能显示,给小程序上架审核造成影响解决方法如下

最近Phpyun系统直接从6.44升级到了v7.0跨度非常大&#xff0c;以前都是0.1的标准升级现在直接跨度这么大升级内容很多&#xff0c;我看了下后台UI都改了 体验确实好了很多&#xff0c;老用户建议升级下&#xff0c;这次升级小程序不用重新上架&#xff0c;完美对接&#xff0c;…

SQL注入的类型之GET基于报错的SQL注入回显分析

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 get类型的基于报错的回显分析 我们可以通过修改URL中的ID参数值来探测是否存在注入漏洞。以下是一些常见的探测方法和实验步骤: 正常数字:将URL中的ID参数值修改为正常的数字(…

Android studio 之 适配器

ListView仅作为容器&#xff08;列表&#xff09;&#xff0c;用于装载 & 显示数据&#xff08;即 列表项Item&#xff09;而容器内的具体数据&#xff08;列表项Item&#xff09;则是由 适配器&#xff08;Adapter&#xff09;提供 适配器&#xff08;Adapter&#xff09…

分布式ID(1):分布式ID简介

1 分布式ID简介 在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。如在美团点评的金融、支付、餐饮、酒店、猫眼电影等产品的系统中,数据日渐增长,对数据分库分表后需要有一个唯一ID来标识一条数据或消息,数据库的自增ID显然不能满足需求;特别一点的如订单、…

《WebKit 技术内幕》学习之八(3):硬件加速机制

3 其他硬件加速模块 3.1 2D图形的硬件加速机制 其实网页中有很多绘图操作是针对2D图形的&#xff0c;这些操作包括通常的网页绘制&#xff0c;例如绘制边框、文字、图片、填充等&#xff0c;它们都是典型的2D绘图操作。在HTML5中&#xff0c;规范又引入了2D绘图的画布功能&a…

YARN节点故障的容错方案

YARN节点故障的容错方案 1. RM高可用1.1 选主和HA切换逻辑 2. NM高可用2.1 感知NM节点异常2.2 异常NM上的任务处理 4. 疑问和思考4,1 RM感知NM异常需要10min&#xff0c;对于app来说是否太长了&#xff1f; 5. 参考文档 本文主要探讨yarn集群的高可用容错方案和容错能力的探讨。…

【复现】D-Tale SSRF漏洞(CVE-2024-21642)_26

目录 一.概述 二 .漏洞影响 三.漏洞复现 1. 漏洞一&#xff1a; 四.修复建议&#xff1a; 五. 搜索语法&#xff1a; 六.免责声明 一.概述 D-Tale数据可视化插件是后端框架Flask与前端框架React组合产生的一款开源的数据可视化分析插件。 目前支持DataFrame、Series、Mu…

深入理解C语言(2):字符、字符串与内存函数

文章主题&#xff1a;字符、字符串与内存函数&#x1f30f;所属专栏&#xff1a;深入理解C语言&#x1f4d4;作者简介&#xff1a;更新有关深入理解C语言知识的博主一枚&#xff0c;记录分享自己对C语言的深入解读。&#x1f606;个人主页&#xff1a;[₽]的个人主页&#x1f3…

Centos 7.9 服务器环境搭建

Centos 7.9 服务器环境搭建 文章目录 Centos 7.9 服务器环境搭建1、Linux2、宝塔面板3、JDK4、MySQL5、Redis6、Nacos7、Nginx 1、Linux # 查看防火墙状态 systemctl status firewalld# 查看已开放端口命令 firewall-cmd --list-all# 开放端口 firewall-cmd --zonepublic --ad…

简单屏蔽WPforms垃圾留言和无效询盘的方法

简单屏蔽WPforms垃圾留言和无效询盘的方法 发表评论 因为WPforms的可视化操作非常简单&#xff0c;不少外贸网站都使用WPforms来制作询盘表单&#xff0c;而只要网站可以提交留言&#xff0c;就非常容易被垃圾留言骚扰。本文奶爸将给大家介绍两种屏蔽WPforms表单垃圾留言的方…