python小知识2

  1. 既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。
  2. map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。

list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
[‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’]

  1. reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

  1. filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素
  2. sorted()函数也是一个高阶函数,它还可以接收一个key函数来实现自定义的排序,例如按绝对值大小排序
  3. 一个函数可以返回一个计算结果,也可以返回一个函数。
    返回一个函数时,牢记该函数并未执行,返回函数中不要引用任何可能会变化的变量。
  4. 关键字lambda表示匿名函数,冒号前面的x表示函数参数。
    匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
  5. 现在,假设我们要增强now()函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
  6. functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

import functools
int2 = functools.partial(int, base=2)
int2(‘1000000’)
64
int2(‘1010101’)
85
当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

  1. __xxx__特殊变量;__xx私有变量;_xxx请视为私有变量
  2. 如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list,比如,获得一个str对象的所有属性和方法
  3. 正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。
  4. 只允许对Student实例添加name和age属性。
    为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性

class Student(object):
__slots__ = (‘name’, ‘age’) # 用tuple定义允许绑定的属性名称

  1. @property广泛应用在类的定义中,可以让调用者写出简短的代码,同时保证对参数进行必要的检查,这样,程序运行时就减少了出错的可能性。
  2. 由于Python允许使用多重继承,因此,MixIn就是一种常见的设计。
    只允许单一继承的语言(如Java)不能使用MixIn的设计。
  3. __str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。
  4. 如果一个类想被用于for … in循环,类似list或tuple那样,就必须实现一个__iter__()方法,该方法返回一个迭代对象,然后,Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。
  5. 要表现得像list那样按照下标取出元素,需要实现__getitem__()方法
  6. 写一个__getattr__()方法,动态返回一个属性,注意,只有在没有找到属性的情况下,才调用__getattr__
  7. 任何类,只需要定义一个__call__()方法,就可以直接对实例进行调用
  8. Python提供了Enum类来实现这个功能:

from enum import Enum
Month = Enum(‘Month’, (‘Jan’, ‘Feb’, ‘Mar’, ‘Apr’, ‘May’, ‘Jun’, ‘Jul’, ‘Aug’, ‘Sep’, ‘Oct’, ‘Nov’, ‘Dec’))

这样我们就获得了Month类型的枚举类,可以直接使用Month.Jan来引用一个常量,或者枚举它的所有成员:

for name, member in Month.members.items():
print(name, ‘=>’, member, ‘,’, member.value)

  1. @unique装饰器可以帮助我们检查保证没有重复值。
  2. 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的。
  3. 正常情况下,我们都用class Xxx…来定义类,但是,type()函数也允许我们动态创建出类来,也就是说,动态语言本身支持运行期动态创建类,这和静态语言有非常大的不同,要在静态语言运行期创建类,必须构造源代码字符串再调用编译器,或者借助一些工具生成字节码实现,本质上都是动态编译,会非常复杂。
  4. 要创建一个class对象,type()函数依次传入3个参数:

class的名称;
继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。

  1. metaclass允许你创建类或者修改类。换句话说,你可以把类看成是metaclass创建出来的“实例”。
    metaclass是Python面向对象里最难理解,也是最难使用的魔术代码。
  2. 凡是用print()来辅助查看的地方,都可以用断言(assert)来替代
  3. logging的好处,它允许你指定记录信息的级别,有debug,info,warning,error等几个级别,当我们指定level=INFO时,logging.debug就不起作用了。同理,指定level=WARNING后,debug和info就不起作用了。这样一来,你可以放心地输出不同级别的信息,也不用删除,最后统一控制输出哪个级别的信息。
  4. doctest非常有用,不但可以用来测试,还可以直接作为示例代码。通过某些文档生成工具,就可以自动把包含doctest的注释提取出来。用户看文档的时候,同时也看到了doctest。
  5. 在Python中,文件读写是通过open()函数打开的文件对象完成的。使用with语句操作文件IO是个好习惯。
  6. StringIO和BytesIO是在内存中操作str和bytes的方法,使得和读写文件具有一致的接口。
  7. 变量从内存中变成可存储或传输的过程称之为序列化
  8. Python语言特定的序列化模块是pickle,但如果要把序列化搞得更通用、更符合Web标准,就可以使用json模块。

json模块的dumps()和loads()函数是定义得非常好的接口的典范。当我们使用时,只需要传入一个必须的参数。但是,当默认的序列化或反序列机制不满足我们的要求时,我们又可以传入更多的参数来定制序列化或反序列化的规则,既做到了接口简单易用,又做到了充分的扩展性和灵活性。

发布了12 篇原创文章 · 获赞 0 · 访问量 512

猜你喜欢

转载自blog.csdn.net/s1421578048/article/details/103990225