有一个jsonline格式的文件file.txt大小约为10K,如何读取内容?
#! -*-conding=: UTF-8 -*-
# 2024/1/19 16:46
def 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:46
def get_lines():
with open('file.txt', 'rb') as f:
for i in f:
yield i
if __name__ == '__main__':
for line in get_lines():
print(line) # 处理每一行数据
个人认为:还是设置下每次返回的内容较好,否则读取次数太多。
#! -*-conding=: UTF-8 -*-
# 2024/1/19 16:46
def 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 _lines
if __name__ == '__main__':
for lines in get_lines():
print(lines) # 处理每两行数据
使用itertools
:
import itertools
def 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]
break
yield [line.strip() for line in _lines]
if __name__ == '__main__':
for lines in get_lines(2):
print(lines) # 处理每两行数据
使用mmap库
from mmap import mmap
def get_lines(fp):
with open(fp, "r+") as f:
m = mmap(f.fileno(), 0)
start = 0
while True:
pos = m.find(b"\n", start)
if pos == -1:
break
yield m[start:pos + 1].decode()
start = pos + 1
if __name__ == '__main__':
for lines in get_lines('file.txt'):
print(lines) # 处理每两行数据
要考虑的问题有:
https://stackoverflow.com/questions/30294146/fastest-way-to-process-a-large-file
请打印指定目录的目录树
#! -*-conding=: UTF-8 -*-
# 2024/1/19 16:46
import os
def 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('.')
#! -*-conding=: UTF-8 -*-
# 2024/1/19 16:46
import datetime
def 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 + 1
if __name__ == '__main__':
print(day_of_year())
import random
alist = [1, 2, 3, 4, 5]
random.shuffle(alist)
print(alist)
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进行排序。
创建一个字典,将列表中的元素作为键,元素的平方作为值
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}
print("aStr"[::-1]) # rtSa
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}
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}]
alist = ['a', 'b', 'c', 'd', 'e']
print(alist[10:]) # []
print([x*11 for x in range(10)]) # [0, 11, 22, 33, 44, 55, 66, 77, 88, 99]
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}
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)
# 如果需要排序的话用sort
alist.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]
import threading
def 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 = 0
def get_id(self):
with threading.Lock():
self.id += 1
return self.id
if __name__ == '__main__':
singleton1 = IdGenerator()
singleton2 = IdGenerator()
print(singleton1 is singleton2) # 输出 True,表示是同一个实例
# 使用 __call__ 方法获取单例
singleton3 = IdGenerator()
print(singleton1 is singleton3) # 输出 True,表示是同一个实例
import threading
class SingletonDecorator:
def __init__(self, cls):
self._cls = cls
self._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] = instance
return self._instances[self._cls]
@SingletonDecorator
class IdGenerator:
def init_generator(self):
self.id = 0
def get_id(self):
with threading.Lock():
self.id += 1
return self.id
if __name__ == '__main__':
singleton1 = IdGenerator()
singleton2 = IdGenerator()
print(singleton1 is singleton2) # 输出 True,表示是同一个实例
# 使用装饰器获取单例
singleton3 = IdGenerator()
print(singleton1 is singleton3) # 输出 True,表示是同一个实例
#! -*-conding=: UTF-8 -*-
# 2023/9/13 18:21
import threading
class 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._instance
def init_generator(self):
self.id = 0
def get_id(self):
with self._lock:
self.id += 1
return self.id
# 使用示例
singleton1 = LazySingleton()
singleton2 = LazySingleton()
print(singleton1 is singleton2) # 输出 True,表示是同一个实例
import threading
class IdGenerator:
_instance = None
_lock = threading.Lock()
def __init__(self):
self.init_generator()
def init_generator(self):
self.id = 0
def get_id(self):
with self._lock:
self.id += 1
return self.id
@classmethod
def get_instance(cls):
if cls._instance is None:
with cls._lock:
if cls._instance is None:
cls._instance = cls()
return cls._instance
if __name__ == '__main__':
singleton1 = IdGenerator.get_instance()
singleton2 = IdGenerator.get_instance()
print(singleton1 is singleton2) # 输出 True,表示是同一个实例
import threading
class 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] = instance
return cls._instances[cls]
class IdGenerator(metaclass=SingletonMeta):
def init_generator(self):
self.id = 0
def get_id(self):
with threading.Lock():
self.id += 1
return self.id
if __name__ == '__main__':
singleton1 = IdGenerator()
singleton2 = IdGenerator()
print(singleton1 is singleton2) # 输出 True,表示是同一个实例
要反转一个整数,可以使用数学运算和字符串操作来实现。
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
第一种方法
import os
def 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 os
def 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("./")
print(sum(range(0, 101)))
复制一份列表操作
a = [1, 2, 3, 4, 5, 6, 7, 8]
print(id(a))
print(id(a[:]))
for i in a[:]:
if i > 5:
pass
else:
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]
全字母短句 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 string
print(string.ascii_lowercase) # abcdefghijklmnopqrstuvwxyz
print("".join(map(chr, range(ord('a'), ord('z') + 1)))) # abcdefghijklmnopqrstuvwxyz
def get_missing_letter(a):
s1 = set(string.ascii_lowercase)
s2 = set(a.lower())
ret = "".join(sorted(s1 - s2))
return ret
print(get_missing_letter("xyz")) # abcdefghijklmnopqrstuvw
1,可变类型有list,dict.不可变类型有string,number,tuple.
2,当进行修改操作时,可变类型传递的是内存中的地址,也就是说,直接修改内存中的值,并没有开辟新的内存。
3,不可变类型被改变时,并没有改变原内存地址中的值,而是开辟一块新的内存,将原地址中的值复制过去,对这块新开辟的内存中的值进行操作。
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
res = [i for i in a if i % 2 == 1]
print(res)
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)
方法一:利用 str 函数
def atoi(s):
num = 0
for v in s:
for j in range(10):
if v == str(j):
num = num * 10 + j
return num
print(atoi("123")) # 123
方法二:利用 ord 函数
def atoi(s):
num = 0
for v in s:
num = num * 10 + ord(v) - ord('0')
return num
print(atoi("123")) # 123
方法三: 利用 eval 函数
def atoi(s):
num = 0
for v in s:
t = "%s * 1" % v
n = eval(t)
num = num * 10 + n
return num
print(atoi("123")) # 123
方法四: 结合方法二,使用 reduce ,一行解决
from functools import reduce
def atoi(s):
return reduce(lambda num, v: num * 10 + ord(v) - ord('0'), s, 0)
print(atoi("123")) # 123
给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用
。
示例:
给定nums = [2,7,11,15],target=9;因为 nums[0]+nums[1] = 2+7 =9,所以返回[0,1]。
class Solution:
@staticmethod
def two_sum(nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
d = {}
size = 0
while 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]] = size
size = size + 1
solution = Solution()
print(solution.two_sum(nums=[2, 7, 11, 15], target=18)) # [1, 2]
方法二:
class Solution(object):
@staticmethod
def 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]
import re
def 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] = 1
else:
distone[keyone] += 1
num_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_ten
print(test("./file.txt")) # ['aaaa', 'dsds', 'sdsdsds']
方法二:
import re
from collections import Counter
def 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"))
该函数的输入是一个仅包含数字的list,输出一个新的list,其中每一个元素要满足以下条件:
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]
该列表只包含满足以下条件的值,元素为原始列表中偶数切片:
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]
result = [x * x for x in range(1, 11)]
方法一:
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 tmp
l1 = [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]
方法一:
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) # 135742
l2 = "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) # 135742
l2 = "568731"
func2(l2) # 135786
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 = one
one = 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 reduce
num = 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
"""
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]
,符合预期的结果。
方法一:
def count_str(str_data):
"""定义一个字符出现次数的函数"""
dict_str = {}
for i in str_data:
dict_str[i] = dict_str.get(i, 0) + 1
return dict_str
dict_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 Counter
print(list(map(lambda x: (x[0], x[1]), Counter("AAABBCCAC").most_common()))) # [('A', 4), ('C', 3), ('B', 2)]
在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()
函数在子类中调用父类方法的场景包括但不限于以下情况:
在Python中,类方法(class method)、类实例方法(instance method)和静态方法(static method)是三种不同类型的方法,它们在使用方式和功能上有一些区别。
类方法(Class Method):
@classmethod
装饰器进行修饰。cls
。类实例方法(Instance Method):
self
。静态方法(Static Method):
@staticmethod
装饰器进行修饰。下面是一个示例,演示了类方法、类实例方法和静态方法的使用:
class MyClass:
class_attr = "Class Attribute"
@classmethod
def 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)
@staticmethod
def 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
修饰,不需要类或实例作为参数,可以通过类或实例调用,但不能访问或修改实例属性和类属性。要遍历一个对象的所有属性并打印每个属性名,你可以使用内置的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()
函数返回的属性列表包括对象的所有属性,包括类定义的属性、继承的属性和一些内置属性。因此,遍历属性时可能会包含一些你不感兴趣的属性。你可以根据自己的需求进行过滤或处理。
自定义int类
class MyNumber:
def __init__(self, value):
self.value = value
def __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.value
elif isinstance(other, int):
return self.value == other
else:
raise TypeError("Unsupported operand type for ==")
def __lt__(self, other):
if isinstance(other, MyNumber):
return self.value < other.value
elif isinstance(other, int):
return self.value < other
else:
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.items
def __str__(self):
return str(self.items)
def __add__(self, other):
if isinstance(other, MyList):
new_list = MyList()
new_list.items = self.items + other.items
return new_list
else:
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_list
else:
raise TypeError("Unsupported operand type for -")
def __mul__(self, other):
if isinstance(other, int):
new_list = MyList()
new_list.items = self.items * other
return new_list
else:
raise TypeError("Unsupported operand type for *")
def __eq__(self, other):
if isinstance(other, MyList):
return self.items == other.items
else:
return False
def __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
Cython、PyPy、CPython和Numba是针对Python代码进行优化的工具和实现方式。它们各自具有不同的优点和缺点,下面是对它们的简要介绍:
Cython:
PyPy:
CPython:
Numba:
需要注意的是,每种工具和实现方式都有其适用的场景。选择合适的工具取决于你的具体需求,如性能要求、代码复杂性、对第三方库的依赖等因素。在实际使用时,可以根据具体情况进行评估和测试,以选择最适合的工具和实现方式。
1.抽象类: 规定了一系列的方法,并规定了必须由继承类实现的方法。由于有抽象方法的存在,所以抽象类不能实例化
。可以将抽象类理解为毛坯房,门窗,墙面的样式由你自己来定,所以抽象类与作为基 类的普通类的区别在于约束性更强。
2.接口类:与抽象类很相似,表现在接口中定义的方法,必须由引用类实现,但他与抽象类的根本区别在于用途
:与不同个体间沟通的规则,你要进宿舍需要有钥匙,这个钥匙就是你与宿舍的接口,你的舍 友也有这个接口,所以他也能进入宿舍,你用手机通话,那么手机就是你与他人交流的接口。
3.区别和关联:
举个栗子:
首先,我们使用抽象类来表示一个动物,并定义一个抽象方法 make_sound
,表示动物发出声音的行为。
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def 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")
现在,我们可以创建 Dog
和 Cat
的实例,并调用它们的 make_sound
方法。
dog = Dog()
dog.make_sound() # 输出: Dog barks
cat = Cat()
cat.make_sound() # 输出: Cat meows
在这个例子中,Animal
是一个抽象类,它定义了一个抽象方法 make_sound
。Dog
和 Cat
是具体的动物类,它们继承了抽象类 Animal
并实现了 make_sound
方法。通过这种方式,我们可以使用抽象类 Animal
来表示一类动物,并要求每个具体的动物类都必须实现 make_sound
方法。
接下来,我们使用接口类来定义一个 Runnable
接口,表示可运行的对象,并定义一个抽象方法 run
,表示对象运行的行为。
class Runnable:
@abstractmethod
def 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中没有明确的语法支持),它定义了一个抽象方法 run
。Car
是一个具体的类,它实现了 Runnable
接口并提供了 run
方法的具体实现。通过这种方式,我们可以使用接口类 Runnable
来表示一类可运行的对象,并要求每个具体的类都必须实现 run
方法。
这就是一个简单的例子,展示了如何使用抽象类和接口类来表示抽象概念并要求子类提供具体的实现。抽象类和接口类在软件设计中起到了规范和约束的作用,帮助我们构建可扩展、灵活的代码架构。
在Python中,可以使用以下方式动态获取和设置对象的属性:
获取属性:
.
):通过对象的名称和属性名称,可以使用点号运算符直接访问对象的属性。obj.attribute # 获取对象obj的attribute属性的值
getattr()
函数:getattr()
函数可以接收一个对象和属性名称作为参数,并返回对象的属性值。如果属性不存在,可以提供一个默认值作为第三个参数。getattr(obj, 'attribute') # 获取对象obj的attribute属性的值
设置属性:
.
):通过对象的名称和属性名称,可以使用点号运算符直接设置对象的属性值。obj.attribute = value # 设置对象obj的attribute属性的值为value
setattr()
函数:setattr()
函数可以接收一个对象、属性名称和属性值作为参数,并将对象的属性设置为指定的值。setattr(obj, 'attribute', value) # 设置对象obj的attribute属性的值为value
需要注意的是,使用动态获取和设置属性的方式可以方便地在运行时根据需要访问和修改对象的属性。但是,如果属性不存在,直接使用点号运算符会引发AttributeError
异常;而使用getattr()
函数可以通过提供默认值来避免异常的抛出。类似地,如果设置属性时,使用点号运算符设置一个不存在的属性会创建一个新的属性,而使用setattr()
函数可以更严格地控制属性的设置行为。
另外,还可以使用hasattr()
函数来检查对象是否具有特定的属性,以及使用delattr()
函数来删除对象的属性。这些函数提供了更多操作对象属性的灵活性和控制性。