download:掌握Java项目面试武功心法,面试弯道超车
“项目面” 的面试官多是项目负责人或技术领导,你很难掩盖技术或开发经验上的欠缺,很多时候面试官不关心你做过什么,而更关心你回答问题的思路、角度和解决问题的方式,那到底该如何回答,这门课给你答案!
适合人群
面临就业问题的在校大学生
面临求职问题的Java工程师
技术储备要求
掌握Java基础
具备至少一个模拟项目开发经验
天都会增加新价格,因此平均值要考虑至目前为止所有的价格。
>>>avg(10)
10.0
>>>avg(20)
15.0
>>>avg(30)
20.0
2、实现方式1:使用类实现
class Averager():
def __init__(self):
self.series = []
def __call__(self, new_value):
self.series.append(new_value)
total = sum(self.series)
return total/len(self.series)
avg = Averager()
print(avg(10)) #10.0
print(avg(20)) #15.0
print(avg(30)) #20.0
函数说明:
1、定义一个类变量保存价格,avg = Averager() 类的实例化,生成实例对象时,创建self.series,是一个数组。
2、call 魔法方法:使得 Averager类的 avg 实例对象变成了可调用对象。
3、每次调用 avg(arg) 时,类变量的列表都增加一个 arg 的元素,返回 列表总和的平均值。
3、实现方式2:使用高阶函数实现(把函数作为参数传入,这样的函数称为高阶函数)
def make_averager():
series = []
def averager(new_value):
series.append(new_value)
total = sum(series)
return total/len(series)
return averager
avg = make_averager()
print(avg.code.co_varnames) #('new_value', 'total')
print(avg.code.co_freevars) #('series',)
print(avg(10)) #10.0
print(avg(20)) #15.0
print(avg(30)) #20.0
print(avg.closure) #(<cell at 0x00000151B2C415E8: list object at 0x00000151B2DA7AC8>,)
print(avg.closure[0].cell_contents) #[10, 20, 30]
函数说明:
调用 make_averager() 时,返回一个 averager 函数对象。每次调用 averager 时,它会把参数添加到系列值中,然后计算平均值。
series 是 make_averager 函数的局部变量
4、方法1和方法2的相通之处和不同之处
相通:
调用 Averager() 或 make_averager() 都得到一个可调用对象 avg,它会更新历史值,然后计算当前均值。
我们只需要调用 avg(n) ,把n放入到系列值中,然后重新计算均值。
不同:
Averager 类的实例 avg 在 self.series 中存储历史值;
make_averager 函数在哪里寻找 series ?series 是 make_averager 函数的局部变量,因为那个函数的定义体中初始化了series, series = [] 。可是调用avg(10)时,make_averager 函数已经返回了,它的本地作用域也一去不复返了。
三、闭包和自由变量
1、闭包和自由变量:在实现方式2的基础上
整个部分称为闭包
series = []
def averager(new_value):
series.append(new_value) # series 称为自由变量
total = sum(series)
return total/len(series)
说明:
averager 的闭包延伸到那个函数的作用域之外,包含自由变量的绑定。
2、func.code
print(avg.code.co_varnames) #('new_value', 'total') 将函数参数和局部变量以元组的形式返回
print(avg.code.co_freevars) #('series',) 返回内部函数中引用外部函数参数,即自由变量(通过函数闭包引用)
更详细的说明参考:
3、func.closure
示例2中
print(avg.closure) #(<cell at 0x00000151B2C415E8: list object at 0x00000151B2DA7AC8>,)
print(avg.closure[0].cell_contents) #[10, 20, 30]
或者遍历得到:
[cell.cell_contents for cell in func.closure]
说明:
Python 3 已将名为func_X 的函数属性重命名为使用 X 形式,从而在函数属性名称空间中为用户定义的属性释放了这些名称。
例如,func_closure,func_code,func_defaults,func_dict,func_doc,func_globals,func_name
分别重命名为closure,code,de