Python备忘录(一)

[复制链接]
发表于 昨天 22:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
在此纪录一些Python中比力常用到的方法本事(连续更新)

天生器

通过列表天生式构建一个天生器

  1. a = [x * x for x in range(10)]    # 列表生成式子生成一个list
  2. print(a)
  3. # 打印:
  4. # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
  5. g = (x * x for x in range(10))    # 列表生成式生成一个生成器,只需将[]替换为()
  6. print(g)
  7. # 打印:
  8. # <generator object <genexpr> at 0x1022ef630>
复制代码

编写一个简单的天生器

  1. def fib(max):
  2.     n, a, b = 0, 0, 1
  3.     while n < max:
  4.         yield b    # 经过迭代操作后生成一个迭代值
  5.         a, b = b, a + b
  6.         n = n + 1
  7.     return 'done'  # 如果已无迭代值,则输出'done'
  8.    
  9. f1 = fib(10)
  10. # 最后一个迭代值出来后,将停止迭代,跳出for语句
  11. for i in f1:
  12.     print(i)
  13. # 打印:
  14. # 1 1 2 3 5 8 13 21 34 55
  15.             
  16. f2 = fib(10)
  17. # 如果想单个迭代,可使用next函数
  18. print(next(f2))
  19. # 打印:
  20. # 1
  21. print(next(f2))   
  22. # 打印:
  23. # 1
  24. print(next(f2))   
  25. # 打印:
  26. # 2
  27. # 这里因为每次fib被next调用时都会生成一个临时的生成器对象,所以输出只会打印第一次的迭代值“1”。
  28. print(next(fib(10)))
  29. print(next(fib(10)))
  30. print(next(fib(10)))
复制代码

map/reduce


map

  1. def f(i):
  2.         return i * i
  3. x = [1, 2, 3, 4, 5, 6, 7, 8]
  4. # map()函数接收两个参数,一个是函数,一个是Iterable。map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回
  5. y = map(f, x)
  6. # 需将Iterator转换为list才能打印出里面的元素
  7. print(list(y))
  8. # 打印:
  9. # [1, 4, 9, 16, 25, 36, 49, 64]
复制代码

reduce

  1. # reduce包含在functools包中,使用时需导入
  2. from functools import reduce   
  3. def fn(x, y):
  4.     return x * 10 + y
  5. def str2int(x):
  6.     strDict = {
  7.         "0": 0,
  8.         "1": 1,
  9.         "2": 2,
  10.         "3": 3,
  11.         "4": 4,
  12.         "5": 5,
  13.         "6": 6,
  14.         "7": 7,
  15.         "8": 8,
  16.         "9": 9,
  17.     }
  18.     return strDict[x]
  19. # reduce接受两个参数,一个是执行函数(需2个参数),一个是Iterable,其大概运行逻辑是:将Iterable按顺序分别传入执行函数中进行操作,然后将返回值执行函数的一个参数后继续与Iterable后面的元素进行操作,直到Iterable没有元素可迭代为止。
  20. ans = reduce(fn, map(str2int, "13579"))
  21. print(ans)
  22. # 打印:
  23. # 13579
复制代码

filter

  1. def is_odd(n):
  2.     return n % 2 == 1
  3. # 和map()类似,filter()也接收一个函数和一个序列。不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。filter返回值是一个Iterator,不方便打印其中的元素,所以将其转换为一个Iterable
  4. print(list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])))
  5. # 打印:
  6. # [1, 5, 9, 15]
复制代码

装饰器

  1. from functools import wraps
  2. # 一、装饰器的基本语法
  3. def log(f):
  4.     # 如果需要打印真正执行操作的函数名而不是wrapper函数名,则需要导入functiools里的wraps
  5.     @wraps(f)
  6.    
  7.     # 如果需要添加装饰器的函数含有参数,则wrapper也需要填入参数(*args, **kw)。
  8.     def wrapper(*args, **kw):
  9.         print('call %s():' % f.__name__)
  10.         return f(*args, **kw)
  11.     return wrapper
  12. # 这个函数用来筛出序列中的偶数,我们如果要针对这个操作插入一些测试/信息说明的话可以使用装饰器来实现。
  13. @log
  14. def func(nums: list) -> list:
  15.     return list(filter(lambda x: x % 2 == 0, nums))
  16. print(func.__name__)
  17. print(func([x for x in range(10)]))
  18. # 打印:
  19. # call func():
  20. # [0, 2, 4, 6, 8]
  21. # 二、带参数的装饰器语法
  22. # 如果装饰器想要接受参数,则需要额外嵌套一层函数。
  23. def log2(text):
  24.     def decorator(f):
  25.         @wraps(f)
  26.         def wrapper(*args, **kw):
  27.             print('%s %s():' % (text, f.__name__))
  28.             return f(*args, **kw)
  29.         return wrapper
  30.     return decorator
  31. @log2('execute')
  32. def func(nums: list) -> list:
  33.     return list(filter(lambda x: x % 2 == 0, nums))
  34. print(func.__name__)
  35. print(func([x for x in range(10)]))
  36. # 打印:
  37. # func
  38. # execute func():
  39. # [0, 2, 4, 6, 8]
复制代码

偏函数

  1. from functools import partial
  2. # 当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。
  3. # 普通写法:
  4. # def int2(x, base=2)
  5. #     return int(x, base)
  6. # 使用partial
  7. int2 = partial(int, base=2)
  8. print(int2('10010'))
  9. # 打印:
  10. # 18
复制代码

__slots__

  1. # python的灵活性可以使类中的属性能够随意添加,为了保证代码的工整和已读可在类中添加一个__slots__变量
  2. class Student:
  3.     __slots__ = ('name', 'age')
  4.    
  5. s = Student()
  6. s.name = 'Sam'
  7. s.age = 16
  8. print(s.name, s.age)
  9. # 打印:
  10. # Sam 16
  11. s.university = "CMU"
  12. print(s.university)
  13. # 报出AttributeError异常,提示Student类中没有"university"属性,也无法设置新属性
复制代码

@property

  1. # python中对于类的属性getter/setter方法可用@property来代替,可读性更高。
  2. class Student(object):
  3.     @property
  4.     def birth(self):
  5.         return self._birth
  6.     @birth.setter
  7.     def birth(self, value):
  8.         self._birth = value
  9.         # age属性没有设置setter,所以如果对其赋值会报错
  10.     @property
  11.     def age(self):
  12.         return 2026 - self._birth
复制代码

罗列类

  1. from enum import Enum
  2. # 构建一个枚举类后,可以直接使用Month.Jan......来引用一个常量,也可以像字典一样遍历它们(需访问__members__)
  3. Month = Enum('Month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))
  4. for k, v in Month.__members__.items():
  5.     print(k, v.value)
  6. # 打印(value属性则是自动赋给成员的int常量,默认从1开始计数):
  7. # Jan 1
  8. # Feb 2
  9. # Mar 3
  10. # Apr 4
  11. # May 5
  12. # Jun 6
  13. # Jul 7
  14. # Aug 8
  15. # Sep 9
  16. # Oct 10
  17. # Nov 11
  18. # Dec 12
  19. print(Month.Jan)
  20. # 打印:
  21. # Month.Jan
  22. print(Month['Feb'])
  23. # 打印:
  24. # Month.Feb
  25. print(Month.Mar.value)
  26. # 打印:
  27. # 3
  28. print(Month['Feb'] == Month.Feb)
  29. # 打印:
  30. # True
复制代码

StringIO和BytesIO

  1. from io import StringIO, BytesIO
  2. # 一、StringIO
  3. f = StringIO()
  4. # 向内存中写入值
  5. f.write("Hello, World !")
  6. print(f.getvalue())
  7. # 打印:
  8. # Hello, World !
  9. # StringIO可设置初始值
  10. f = StringIO("Hello!\nHi!\nGoodbye!")
  11. while True:
  12.     # readline遇到换行符停止读取
  13.     s = f.readline()
  14.     if s == '':
  15.         break
  16.     print(s.strip())
  17.     # 打印:
  18.     # Hello!
  19.     # Hi!
  20.     # Goodbye!
  21.    
  22. # 二、BytesIO
  23. b = BytesIO()
  24. b.write('中文'.encode('utf-8'))
  25. print(b.getvalue())
  26. # 打印:
  27. # b'\xe4\xb8\xad\xe6\x96\x87'
复制代码

JSON

  1. # 如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML。但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
  2. import json
  3. # 一、序列化
  4. d = dict(name="Bob", age=20, score=88)
  5. print(json.dumps(d))
  6. # 打印(输出字符串):
  7. # {"name": "Bob", "age": 20, "score": 88}
  8. # 类的序列化需要自定义一个转换函数,否则json无法解析类的序列化操作,反序列化下同。
  9. class Student(object):
  10.     def __init__(self, name, age, score):
  11.         self.name = name
  12.         self.age = age
  13.         self.score = score
  14. # 类的序列化函数
  15. def student2dict(stu: Student):
  16.     return {"name": stu.name, "age": stu.age, "score": stu.score}
  17. stu = Student("Sam", 20, 88)
  18. print(json.dumps(stu, default=student2dict))
  19. # 打印(输出字符串):
  20. # {"name": "Sam", "age": 20, "score": 88}
  21. # 因为通常class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量。也有少数例外,比如定义了__slots__的class。
  22. print(json.dumps(stu, default=lambda x: x.__dict__))
  23. # 打印(输出字符串):
  24. # {"name": "Sam", "age": 20, "score": 88}
  25. # 二、反序列化
  26. # 注意在Python中进行反序列化操作时,反序列化字符串(即JSON对象)中的成员必须是双引号
  27. d = json.loads('{"name": "Bob", "age": 20, "score": 88}')
  28. print(d)
  29. # 打印(输出字典):
  30. # {'name': 'Bob', 'age': 20, 'score': 88}
  31. # 类的反序列化函数
  32. def dict2Student(d: dict[str, any]):
  33.     return Student(d["name"], d["age"], d["score"])
  34. stu_dict = json.loads('{"name": "Bob", "age": 20, "score": 88}')
  35. stu = dict2Student(stu_dict)
  36. print(stu.name, stu.name, stu.score)
  37. # 打印:
  38. # Bob Bob 88
复制代码


免责声明:如果侵犯了您的权益,请联系站长及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金.
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表