IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 读书笔记:《流畅的Python》第五章 一等函数 -> 正文阅读

[Python知识库]读书笔记:《流畅的Python》第五章 一等函数

# 一等对象/一等函数
'''
1.在运行时创建
2.能赋值给变量或数据结构中的元素
3.能作为函数的参数传给函数
4.能作为函数的返回值返回结果
'''

# 函数对象本身时function对象的实例

def factorial(n):
    '''return n!'''
    return 1 if n < 2 else n*factorial(n-1)

"""
print(factorial(42))
print(factorial.__doc__) # 打印函数说明
print(type(factorial))

fact = factorial # 把函数赋值给变量
print(fact)
print(fact(5))

res = list(map(factorial,range(11)))
print(res)
"""

# 高阶函数 : 接受函数为参数,或者把函数作为返回的结果
# map,reduce,filter,sorted

# map,reduce,filter的现代替代者

# map和filter和列表推导式比较
"""
print(list(map(factorial,range(6))))
print([factorial(n) for n in range(6)])

print(list(map(factorial,filter(lambda n:n%2,range(6)))))
print([factorial(n) for n in range(6) if n%2])
"""

# 使用reduce和sum计算0-99的和
"""
from functools import reduce
from operator import add

print(reduce(add,range(100)))
print(sum(range(100)))
"""

# 其他内置归约函数 all any
"""
print(all([1,1,1,1]))
print(all([]))
print(any([1,0,0,0]))
print(any([]))
"""

# 使用lambda表达式反转拼写
"""
fruits = ['strawberry','fig','apple','cherry','raspberry','banana']
res = sorted(fruits,key=lambda word:word[::-1])
print(res)
"""

# 如果lambda表达式难以理解,重构的方法
# 编写注释,说明lambda表达式的作用
# 研究一会儿注释,并找出一个名称来概括注释
# 把lambda表达式转换成def语句,使用那个名称来定义函数
# 删除注释

# 可调用对象
"""
    1.用户定义的函数
    2.使用def或者lambda表达式创建
    3.内置函数
    4.使用C语言(cpython)实现的函数,如len或者time.strftime
    5.内置方法
    6.使用c语言实现的方法,如dict.get
    7.方法
    8.在类的定义中定义的函数
    9.类
        调用类的过程:
            运行__new__创建一个实例
            运行__init__初始化实例
            把实例返回给调用方
    10.类的实例
        如果类定义了__call__方法,那么它的实例可以作为函数调用
    11.生成器函数 使用yield关键字的函数或者方法,调用生成器函数返回的是生成器对象
    判断是否可调用,可以实用内置函数callable()
"""

"""
print(abs)
print(str)
print([callable(n) for n in (abs,str,int,13.0)])
"""

# 用户定义的可调用类型
"""
import random
class BingoCage:
    '''定义一个类,完成了__call__方法
    让这个类的实例表现得像一个函数
    这个类的实例由任何可迭代对象创建,
    调用实例会取出一个元素'''
    def __init__(self,items):
        self._items = list(items)
        random.shuffle(self._items)

    def pick(self):
        try:
            return self._items.pop()
        except IndexError:
            raise LookupError('pick from empty BingoCage')

    def __call__(self):
        return self.pick()

if __name__ == '__main__':
    bingo = BingoCage(range(3))
    print(bingo.pick())
    print(bingo())
    print(callable(bingo))
"""

# 函数内省
# print(dir(factorial))

# __dict__ : 函数用来存储赋予它的用户属性

# 常规对象没有而函数有的属性
"""
class C:pass
c = C()
def func():pass

print(sorted(set(dir(func)) - set(dir(c))))
# ['__annotations__',:参数和返回值的注解
# '__call__', :实现()运算符,即可调用对象协议
# '__closure__', :函数闭包,即自由变量的绑定,通常为None
# '__code__',:编译成字节码的函数元数据和函数定义体
# '__defaults__',:形式参数的默认值
# '__get__', :实现只读描述符协议
# '__globals__', :函数所在模块中的全局变量
# '__kwdefaults__',: 仅限关键字形式参数的默认值
# '__name__',:函数名称
# '__qualname__':函数的限定名称,如random.choice]
"""

# 从定位参数到仅限关键字参数
# tag函数用于生成html标签,使用名为cls的关键字传入"class"属性,这是一种变通的方法,\
# 因为class是python的关键字

def tag(name,*content,cls = None,**attrs): # cls是一个仅限关键字参数
    '''生成一个html标签'''
    if cls is not None:
        attrs['calss'] = cls
    if attrs:
        attr_str = ''.join(' %s="%s"'%(attr,value)
                           for attr,value in sorted(attrs.items()))
    else:attr_str = ''

    if content:
        return '\n'.join('<%s %s>%s</%s>'%(name,attr_str,c,name) for c in content)
    else:
        return '<%s %s />'%(name,attr_str)


"""print(tag('br')) # 传入单个位置参数
print(tag('p', 'hello')) # 第一个参数后面的任意个参数会被*content捕获,存入一个元组
print(tag('p', 'hello','world')) 
print(tag('p', 'hello',id = 33)) # 没有明确指定名称的参数会被**attrs捕获,存入一个字典
print(tag('p', 'hello','world',cls='sidebar')) # cls参数只能作为关键字参数传入
print(tag(content = 'testing',name='img')) # 第一个位置参数也能作为关键字参数传入

my_tag = {'name':'img','title':'Sunset Boulevard',
          'src':'sunset.jpg','cls':'framed'}
print(tag(**my_tag)) # 拆包 同名的键会被绑定到具名的参数上,余下的则被**attrs捕获
"""

# 如果不想支持数量不定的位置参数,但是想支持仅限关键字参数,在签名中放一个*

"""def f(a,*,b): # b必须强制传入关键字参数
    return a,b


print(f(1, b=2)) # (1,2)
# print(f(1, 2)) # 报错
print(f(1)) # 报错  必须传入b的关键字参数
"""

# 获取关于参数的信息

"""import bobo
@bobo.query('/')
def hello(person):
    return 'hello %s!'%person
    
print(hello('丁小马'))
"""

# 在指定长度截取字符串的函数

"""def clip(text,max_len = 80):
    '''在manx_len的前面或者跟后面的第一个空格处截断文本'''
    end = None
    if len(text) > max_len:
        space_before = text.rfind(' ',0,max_len)
        if space_before >= 0 :
            end = space_before
        else:
            space_after = text.rfind(' ',max_len)
        if space_after >= 0:
            end = space_after
    if end is None: # 没找到空格
        end = len(text)

    return text[:end].rstrip()


print(clip.__defaults__) # >>>(80,)
print(clip.__code__) # >>><code object clip at 0x00000281885292F0, file "E:\pythonProjects\pythonProject\读书笔记\流畅的Python\04第五章一等函数\__init__.py", line 205>
print(clip.__code__.co_varnames) # >>>('text', 'max_len', 'end', 'space_before', 'space_after')
print(clip.__code__.co_argcount) # >>>2
"""


# 提取函数的签名

"""from inspect import signature
sig = signature(clip)
print(sig)

for name,param in sig.parameters.items():
    print(param.kind,':',name,'=',param.default)
# POSITIONAL_OR_KEYWORD : text = <class 'inspect._empty'> 表示没有默认值
# POSITIONAL_OR_KEYWORD : max_len = 80
# .kind属性的值
#     POSITIONAL_OR_KEYWORD:可以通过位置参数和关键字参数传入的形参
#     VAR_POSITIONAL : 定位参数元组
#     VAR_KEYWORD : 关键字参数字典
#     KEYWORD_ONLY : 仅限关键字参数
#     POSITIONAL_ONLY : 仅限位置参数
"""

#  把tag函数的签名绑定到一个参数字典上

"""import inspect
sig = inspect.signature(tag) # 获取函数签名
my_tag = {'name':'img','title':'Sunset Boulevard',
          'src':'sunset.jpg','cls':'framed'}
bound_args = sig.bind(**my_tag) # 将实参绑定给函数调用中的形参
print(bound_args)
for name,value in bound_args.arguments.items():
    print(name,'=',value)
del my_tag['name']
bound_args = sig.bind(**my_tag) # 报错缺少了 name参数
"""

#函数注解

def clip(text:str,max_len:'int > 0' = 80)->str: # 有注解的函数声明
    '''在manx_len的前面或者跟后面的第一个空格处截断文本'''
    end = None
    if len(text) > max_len:
        space_before = text.rfind(' ',0,max_len)
        if space_before >= 0 :
            end = space_before
        else:
            space_after = text.rfind(' ',max_len)
        if space_after >= 0:
            end = space_after
    if end is None: # 没找到空格
        end = len(text)

    return text[:end].rstrip()


print(clip.__annotations__) # 注解存放在这个属性里


#从函数签名中提取注解
from inspect import signature
sig = signature(clip)
print(sig.return_annotation)

for param in sig.parameters.values():
    note = repr(param.annotation).ljust(13)
    print(note,':',param.name,'=',param.default)

operator?和?functools模块介绍


# 计算阶乘
# operator包提供兼用运算符的函数形式

"""from functools import  reduce
from operator import mul

def fact(n):
    return reduce(mul,range(1,n+1))

print(fact(5))

# itemgetter(): 构建一个函数,返回序列的某个位置上的值
# itemgetter(1) 作用等同于 lambda fields:fields[1]
# 使用itemgetter排序一个元组列表
metro_data= [('Tokyo','JP',36.933,(35.689722,139.691667)),
               ('New Yory','US',20.104,(40.808611,-74.020386)),
             ('Delhi NCR','IN',21.935,(28.613889,77.208889)),
             ('Mexico City','MX',20.124,(19.43333,-99.113333)),
             ('Sao Paulo','BR',19.649,(-23.547778,-46.638533))]

from operator import itemgetter
for city in sorted(metro_data,key=itemgetter(1)):
    print(city)

# 如果把多个参数传给itemsgetter,它构建的函数会返回提取的值构成的元组

cc_name = itemgetter(1,0)
for city in metro_data:
    print(cc_name(city))

# attrgetter:创建的函数根据名称提取对象的属性

# 定义一个namedtuple,演示使用attrgetter处理它

from collections import namedtuple
LatLong = namedtuple('LatLong','lat long')
Metropolis = namedtuple('Metropolis','name cc pop coord')
metro_areas = [Metropolis(name,cc,pop,LatLong(lat,long))
               for name,cc,pop,(lat,long) in metro_data]
print(metro_areas[0])
print(metro_areas[0].coord.lat)

from operator import attrgetter

name_lat = attrgetter('name','coord.lat')
for city in sorted(metro_areas,key=attrgetter('coord.lat')):
    print(name_lat(city))
"""


"""import operator
# operator中的函数
print([name for name in dir(operator) if not name.startswith('_')])
#['abs', 'add', 'and_', 'attrgetter', 'concat', 'contains', 'countOf', 
# 'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt', 'iadd', 'iand', 
# 'iconcat', 'ifloordiv', 'ilshift', 'imatmul', 'imod', 'imul', 'index',
# 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift', 'is_', 'is_not',
# 'isub', 'itemgetter', 'itruediv', 'ixor', 'le', 'length_hint', 'lshift', 
# 'lt', 'matmul', 'methodcaller', 'mod', 'mul', 'ne', 'neg', 'not_', 'or_',
# 'pos', 'pow', 'rshift', 'setitem', 'sub', 'truediv', 'truth', 'xor']
"""

# methodcaller

"""from operator import methodcaller
s = 'The time has come'
upcase = methodcaller('upper')
print(upcase(s))
hiphenate = methodcaller('replace',' ','_')
print(hiphenate(s))
"""

# 使用functools.partial冻结参数
# functools提供了一些列高阶函数
# functools.partial用于部分应用一个函数:
#     基于一个函数创建一个新的可调用对象,把原函数的某些参数固定
#     使用和这个函数可以把接受一个或者多个参数的函数改编成需要会回调的API,这样参数更少
# functools.partial的第一个参数是一个可调用对象,后面是任意个要绑定的位置参数和关键字参数
# 使用partial把一个两个参数的函数改编成需要单参数的可调用对象

from functools import partial
from operator import mul

triple = partial(mul,3) # 固定住做乘法的其中一个数为3
print(triple(7))

print(list(map(triple, range(1, 10))))


def tag(name,*content,cls = None,**attrs): # cls是一个仅限关键字参数
    '''生成一个html标签'''
    if cls is not None:
        attrs['calss'] = cls
    if attrs:
        attr_str = ''.join(' %s="%s"'%(attr,value)
                           for attr,value in sorted(attrs.items()))
    else:attr_str = ''

    if content:
        return '\n'.join('<%s %s>%s</%s>'%(name,attr_str,c,name) for c in content)
    else:
        return '<%s %s />'%(name,attr_str)

picture = partial(tag,'img',cls = 'pic-frame')
print(picture(src='wupus.jpeg'))
print(picture)
print(picture.func)
print(picture.args)
print(picture.keywords)

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-10-30 12:31:14  更:2021-10-30 12:31:53 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 22:54:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码