python笔记-编程优化NO3(阅读笔记-流畅的python)+【字节内推】

有内推需要的小伙伴可以联系我~

刚刚入职字节广告部门,面经之前发的几篇博客有,大家加油ovo

可以私信我(一般晚上回信,白天上班ovo),也可以直接用我的内推码(文末)

 

 

1.闭包+装饰器

2.__repr__和__str__

3.拆包相关

4.字典相关

 

1.闭包+装饰器

闭包:一个函数包含了一个函数,并且返回了那个函数。在修饰器中用的很多。

装饰器:装饰器是一个函数,接受一个函数或方法作为其唯一的参数,并返回一个新函数或方法,其中整合了修饰后的函数或方法,并附带了一些额外的功能.

#闭包
def outer():
    x = 10

    def inner():   # 内部函数
        print(x)    # 外部函数的一个变量

    return inner

# 调用inner()函数的方法
outer()()   # 法一

f = outer()
f()         # 法二
def function(func):
    # 两个def之间的代码仅会在@function时候运行一次,其他时候均不会运行
    def inner(*args):
        print("before")
        print(args)
        func(*args)
        print("after")

    return inner


@function  # 相当于 f = function(f)
def f(*args):
    print(*args)
    pass

f("new","old")

https://www.cnblogs.com/ss-long/p/10385753.html

装饰器事例:https://www.cnblogs.com/ss-long/p/10427778.html

闭包要注意尽量减少使用循环变量,容易产生闭包陷阱。闭包保存的仅仅是变量名,并没有立刻保存该变量指向的值,因为有的时候引用的变量值是在变化的,在闭包被调用之前,它引用的不是变量指向的具体值,只有在闭包被调用的时候,它才会去查找这些变量的值。

#会产生闭包陷阱,输出的都是4
def my_func(*args):
    #my_func到func之间的代码仅会在出现my_func()时候运行一次
    fs = [] 
    for i in xrange(3):
        def func():
            return i * i
        fs.append(func)
    return fs

fs1, fs2, fs3 = my_func()
print fs1()
print fs2()
print fs3()


#如果非要使用循环变量,1.可以用直接赋值的方法;2.使用yield一起延迟,随用随取

#方法一

def my_func(*args):
    fs = []
    for i in xrange(3):
        def func(_i = i):
            return _i * _i
        fs.append(func)
    return fs
fs1, fs2, fs3 = my_func()
print fs1()
print fs2()
print fs3()

#方法二

def my_func(*args):
    fs = []
    for i in xrange(3):
        def func():
            return i * i
        yield func

for f in my_func():
    print f()
#类装饰器 :目前查到有两种类装饰器(百度上ovo)。一种是类装饰方法,类装饰器;另一种方法装饰类,类的装饰器。:)

通过实现__call__方法来实现装饰功能
>>> import time
>>> class Foo():
...     def __init__(self, func):    # 初始化函数中传入函数对象的参数
...         self._func = func
...     def __call__(self):    # 定义__call__方法,直接实现装饰功能
...         start_time = time.time()
...         self._func()
...         end_time = time.time()
...         print('花费了 %.2f' % (end_time - start_time))
... 
>>> @Foo  # bar=Foo(bar)
... def bar():
...     print('bar函数的执行时间为:')
...     time.sleep(2.5)
... 
>>> bar()    # bar=Foo(bar)(),没有嵌套关系了,直接执行Foo的 __call__方法,实现装饰功能   
bar函数的执行时间为:
花费了 2.51

第二种,通过先运行装饰方法来处理要加载的累
def typed(**kwargs):
    def deco(obj):
        for k, v in kwargs.items():
            setattr(obj, k, v)
        return obj

    return deco


@typed(x=1, y=2, z=3)  # 1、typed(x=1, y=2, z=3)->deco  2、@deco->Foo=deco(Foo)
class Foo:
    pass


 

2.__repr__和__str__:都是返回一个当前对象的字符串。

repr应更准确,无歧义;在没有str方法时会用repr代替。format中使用填入对象的时候会调用repr方法

str更偏向用户,只有在调用str()的时候被使用。

PS:%和format区别 https://www.cnblogs.com/nulige/p/6115793.html

 

3.拆包

_单个占位;*多个占位,可接受多个元素,在赋值的时候可以拆分可迭代对象,如list,tuple

字典使用现成列表中的列表推导式中可以配合拆包。

information = [(10, "china"), (11, 'japan')]
country = {country: num for num, country in information if num == 10}
#将china和10的位置换了一下,筛选出序号为10的国家

PS:利用collections.namedtuple 是一个工厂函数,它可以用来构建一个带字段名的元组和一个有名字的类——这个带名字的类对调试程序有很大帮助。

 

4.字典相关

在设置字典默认值的时候使用setdefault

my_dict.setdefault(key, []).append(new_value)

if key not in my_dict:
 my_dict[key] = []
my_dict[key].append(new_value)

第一种方法等价于第二种,但第二种会对key进行多次检索,如果key不在,对进行3次检索。

可以通过重写__missing__方法来避免抛出keyerror的异常。

MappingProxyType 来获取字典的只读实例 mappingproxy
 
 

左边是社招,右边是校招~

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值