有内推需要的小伙伴可以联系我~
刚刚入职字节广告部门,面经之前发的几篇博客有,大家加油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的异常。
![](https://i-blog.csdnimg.cn/blog_migrate/84310f7c74301741ff2c672563f83f5d.png)
左边是社招,右边是校招~