文章目录
- 1. 如何在一个函数内部修改全局变量
-
- 2. 字典如何删除键和合并两个字典
-
- 4. 简述with方法打开处理文件帮我们做了什么?
- 5. 列表[1,2,3,4,5],请使用map()函数输出[1,4,9,16,25],并使用列表推导式提出大于10 的数,最终输出[16,25]
-
- 6. Python中生成随机整数,随机小数,0-1之间小数的方法
-
1. 如何在一个函数内部修改全局变量
① python中什么是全局变量
- 全局变量就是在函数体外声明的变量
- 函数体内声明的变量是局部变量.
② 全局变量如果出现在函数的作用域内,有什么特性
- 可以直接访问全局变量
- 但是不能直接赋值,直接赋值的时候,编译器会认为是重新创建了一个局部变量,只是这个局部变量和全局变量重名,然后会把全局的变量覆盖掉.
③ 如何在函数作用域(局部作用域内)修改全局变量的值呢?
- 需要借助
global 关键字声明 global 声明会告诉编译器,这个变量是全局变量,然后在使用和编译的时候就会当成全局变量来使用.
2. 字典如何删除键和合并两个字典
① 删除键
方法1: 第一反应是pop
从上面的示例可以看出来,字典的pop(key) 确实可以删除字典的键,但是有两个要求
pop(key) 函数没有默认参数,必须提供一个参数键.pop(key) 参数key必须是字典中存在的键,否则就会报错
解法2: 第二反应是remove,不确定remove可不可以,尝试一下.
尝试失败,字典中没有remove 方法,然后使用dir(dict) 看看字典的一些属性方法:如下
注意看这里有一个popitem 方法,这个方法和pop 有什么区别呢? 我们看看官方的解释怎么说?
翻译一下: 大概的意思就是移除掉确定的key (参数传递进来的),并且返回它对应的value .如果key 不存在,如果提供了默认值,就返回默认值,如果没有提供,就报KeyError
可以看出来 popitem() 是没有参数要求的,它是移除掉一个键值对,并且返回,但是具体移除哪个键值队不能明确.如果字典为空,就报KeyError
第三反应: del
del dct[key] 的方式也可以删除字典的键,在key 不存在的时候也报错.返回值是None
② 合并两个字典
方法1: 记忆中有个update方法用来合并字典的,但是具体的应用不是很清晰了.我们看下文档怎么说?
[E,]**F -> None. 这是个啥? 不要急,遇到这种事情,我也感觉很烦躁,为啥别人写的文档,我们看不懂.先慢慢看.
[E,] 这种带中括号[] 的都表示这个参数是可选参数,可以提供,也可以不提供,就是这个函数的定义中有默认的参数了. **F 表示 它接收数量可变的关键字参数作为F . 如果E 提供了并且有一个keys() 方法, 然后就遍历它,赋值给D 如果E 提供了但是没有keys() 方法,然后就遍历k,v,进行赋值 无论是哪种情况,都会执行 for k in F: D[k] = F[k]
先看看只有E的情况以及E和F同时存在的情况:
再看看只有F的情况:
方法3: 构造函数 dict(d1,**d2)
显而易见,这种方式有一个局限,那就是第二个字典必须是字符串作为键才行.
方法4: 字典推导式
注意: 这个字典推导式是双层的嵌套的,因为要先遍历两个字典,然后每个字典分别使用推导式来进行赋值推导.
方法5: 元素拼接,通过列表拼接,然后转换为字典
方法6: 字典拆分法,通过大括号{},可以直接组成新字典
newDict = {**d1,**d2,**d3,...}
③ 简述面向对象中__init__ 和__new__ 的区别?
区别主要从两个方面来说: 功能上来讲:
__init__ 主要是用来初始化对象,它调用的前提是必需__new__ 返回了当前的对象的时候,__init__ 才会被调用.__new__ 对象构造的时候,通过__new__ 来创建一个当前对象的实例.
调用的时机和条件:
__new__ 一般是不需要定义的,它由编译器自动创建,在创建对象的时候,先调用__new__ .__init__ 一般需要自己定义,用来指定自己的个性化初始化,在创建对象的时候,先调用__new__ ,正常来讲这个__new__ 会返回一个当前对象的实例,如果返回了当前对象的实例会自动调用__init__ 方法,如果没有则__init__ 方法不会被调用
参数和返回值:
__new__() 至少要有一个cls 参数,代表当前的类,此参数在实例化的时候由Python 解释器自动识别.一般是要返回当前的实例.__init__() 至少要有一个参数self ,这个self 其实就是__new__ 返回的实例.一般是返回None
看下如果__new__没有返回当前实例的情况,还有就是__new__这个参数cls到底是个什么东西?
可以看到 __new__() 当中的这个cls 其实就时Person类,但是上面我们返回的不是Person 的实例对象,所以__init__ 根本就没有调用.
可以看到如果使用Person 类去实例化对象,__init__ 就会被调用. 这里直接用object.__new__(Person) 其实和 super().__new__(cls) 是等价的.
4. 简述with方法打开处理文件帮我们做了什么?
打开文件不用with的写法: 注意: 这里a.txt 不能存在就报了异常.所以我们加入了try catch ,又因为最后无论如何都要关闭文件流,我们再加一个finally.
从上面的示例中可以看到with语句做了什么事情.
with语句的实现原理:
with 语句的实现是通过上下文管理器来 实现的,不是所有的方法都可以实现with语句,只有那种实现了上下文管理协议的才能使用with 语句.
上下文管理器协议
__enter__(self) 方法,with 语句开始运行的时候,会在上下文管理器上调用__enter__ 方法,这个函数一般返回一个对象,一般是自身,此函数的返回值分配给变量following as 后面的那个变量上面.__with__ 语句运行结束的时候,会在上下文管理对象上调用__exit__(self,exc_type,exc_value,traceback) 方法,以此扮演finally 子句的角色.我们看看这三个参数到底是个什么玩意 exc_type,exc_val, exc_tb
写一个上下文管理器,然后看看怎么运行的.
本质上,如果从块内的任何地方抛出了异常,则将__exit__() 调用该对象的函数.如您所见,与引发的异常关联的类型,值和堆栈跟踪将传递给此函数.在这种情况下,您可以看到ZeroDivisionError 抛出异常.实现库的人员可以在其__exit__() 功能中编写清理资源,关闭文件等代码.
5. 列表[1,2,3,4,5],请使用map()函数输出[1,4,9,16,25],并使用列表推导式提出大于10 的数,最终输出[16,25]
① map的使用
我的第一反应map 是一个映射函数,前面是一个可迭代的序列,后面是对应的映射方法,应该是长这个样子的 map(iterable,somefunction)
下面测试下: 这里明显不对,说函数是不可以迭代的. 难道是我记反了,前面是映射方法,后面是可迭代对象,我再试试.
果然,是记错了.前面是映射的方法,后面才是可迭代对象,所以我在做这个题的时候,就引申出来一个思考,为啥不能前面是可迭代对象,后面是映射方法呢?
答案是很简单的,因为可迭代对象可能有多个,但是映射方法只能有1个,看下下面的用两个可迭代对象进行映射的例子:
如果多个可迭代对象的个数不一样呢,只要有一个迭代结束,映射就结束. 然后研究到这里的时候,其实我还是很好奇,如果可迭代对象的个数,大于映射的参数的个数的时候,会发生什么? 可以看到报错了,同理,如果参数太少,也是会报错.
② 解答:
所以知道了map 的用法,上面的答案就容易搞定了,就是直接用带条件的列表推导式再求一层就能解决.
6. Python中生成随机整数,随机小数,0-1之间小数的方法
① random.randint(start,end)
我首先想到的是这个,生成随机的整数.具体对不对,我们去看看,测试下.
好了,现在我们查看一下这个函数的说明:
翻译君给大家翻译一下: 就是返回一个[a,b] 之间的一个整数,包含a 和b . 如果验证,包含a 和b 呢
② random.random()
我印象中生成小数的有一个这样的函数,到底有没有,还是要去验证一下. 果然有,这个函数返回的是[0,1) 的一个浮点数,注意这类不包括1,但是包括0.
③ random.rand()
我记得好像有这个函数,但是记得不太清楚了,去验证一下: 事实证明,是没有的,具体有什么函数呢? 我们使用dir(random) 看下
这里面有很多的函数,我们先看看哪个比较像我们找的.我们先看看randrange() 是个什么东西?
翻译君翻译一下: 得到一个随机整数,从range(start,stop[,step])范围内,这个解决了randint() 中包含最后那个点的问题.有些时候,可能不需要最后那个点被随机到,就可以使用这种方法.
这个虽然也是求随机数,但是明显不是我们要找的那个求随机小数的方法,我们继续看下一个.
sample()像不像? 这里我真的没什么印象,就直接看文档吧.
啊,好长,突然就像放弃了,但是既然遇到了,就研究下这个东西是个啥吧? 翻译君翻译中....... 简单的解释就是从 population 这个序列或者是集合当中选择k 个唯一的随机元素.
返回一个新的列表包含从population 中选取的元素,并且维持population 中的元素不变. 结果列表按照顺序排列,所以所有的子片都是有效的随机样本.
这允许抽奖获胜者(本样本)可以进行分区,分成一等奖和二等奖(子列)
样本集合中的数据不必是可哈希或者是唯一的,如果样本中包含重复的元素,那么重复的元素的每一个都可能是样本的选择.这个不确定的.
要在整数范围内选择一个样本,请使用range() 作为参数.对于从a 总采样,这是特别快速和节省空间的.
搞到了这里之后,其实我对于那个一等奖和二等奖还不是很理解,我想大概意思就是它的子序列依旧可以当成一个完整的随机序列的意思.
然后去看看那个 uniform()函数,这个是在查资料的时候发现的,这个就是生成范围内随机小数的.
看看官方文档怎么说?
根据四舍五入的情况获取[a,b]或者[a,b)的随机数,也可能是随机小数.
|