当前位置: 首页 > 科技观察

快来挑战这十道Python题,你会吗?

时间:2023-03-15 17:02:06 科技观察

大家好,我是郑哥。Python入门容易,但精通并不容易。即使是经验丰富的工程师,有些现象也是违反直觉的。下面这10道题很有趣也很有挑战性,结果可能会让你一头雾水,看看你能答对几个?这里先给出问题,最后给出答案。建议拿一张纸,写下你的答案,最后验证一下。请编写以下代码的输出:1.LazyPythonclassA:deffunction(self):returnA()a=A()A=intprint(a.function())2.Rounding>>>round(7/2)>>>round(3/2)>>>round(5/2)3.typeandobject>>>isinstance(type,object)>>>isinstance(object,type)>>>isinstance(object,object)>>>isinstance(type,type)4.空布尔值>>>any([])>>>all([])5.类内部函数的优先级classA:answer=42def__init__(self):self.answer=21self.__add__=lambdax,y:x.answer+ydef__add__(self,y):returnself.answer-yprint(A()+5)6.sum>>>sum("")>>>sum("",[])>>>sum("",{})7.意外属性>>>sum([el.imagforelin[0,5,10e9,float('inf'),float('nan')]])8.输出一个负数倍数的字符串>>>"这是一个很长的字符串"*(-1)9.见负数0max(-0.0,0.0)10.违反数学规则>>>x=(1<<53)+1>>>x+1.0>x答案及解释以下结果在Python3.8.5版本中得到验证。1.LazyPythonclassA:deffunction(self):returnA()a=A()A=intprint(a.function())正确结果为0:这个不难,因为Python的函数定义其实可以执行语句,函数在调用之前不存在,真正调用时会绑定变量。在上面的示例中,在函数定义期间,Python允许引用尚未定义的类或函数。但是在执行过程中,A已经是int类了,也就是说function方法会返回一个新创建的int实例,int实例的默认值为0。如果没有A=int,结果将是:2.舍入>>>round(7/2)4>>>round(3/2)2>>>round(5/2)2正确的结果是422,你一定觉得最后的round(2.5)==2有点数学违规,因为Python的round方法实现了银行家舍入[1],其中所有半值都舍入到最接近的偶数。3.类型和对象>>>isinstance(type,object)True>>>isinstance(object,type)True>>>isinstance(object,object)True>>>isinstance(type,type)True>>>bothTrue,我想知道object和true是一回事吗?在Python中,一切皆对象,因此对对象的任何实例检查都将返回True。isinstance(Anything,object)#=>真。type表示用于构造所有Python类型的元类。因此,所有类型:int、str、object都是类型类的实例,它和python中的所有对象一样,也是一个对象。但是type是Python中唯一一个自身实例的对象。>>>type(1)>>>type(int)>>>type(type)>>>4.空布尔值>>>任意([])False>>>all([])True>>>any([True,False])True>>>all([True,False])False>>>当参数为空列表时,any和all的结果有些出乎意料。但是如果理解了它的检查逻辑,就说得通了:Python中的逻辑运算符是惰性的,any的算法就是寻找第一次出现的真元素,找不到就返回False。由于序列为空,没有元素可以为真,所以any([])返回False。同理,all算法就是寻找第一个假元素。如果未找到,则返回True。由于空序列中没有false元素,all([])返回True。是不是有点空洞的真理概念?5.类内部函数优先级A类:answer=42def__init__(self):self.answer=21self.__add__=lambdax,y:x.answer+ydef__add__(self,y):returnself.answer-yprint(A()+5)正确的结果是:16:对象函数的查找顺序是:实例级>类级>父类级。上面代码中,初始化时绑定的函数是实例级别的,类内部定义的函数是类级别的。但是用双下划线包裹的魔术函数不包括在这个规则中,也就是说,Python首先寻找类级别的魔术函数。如果去掉双下划线,则结果为26:6.Sum>>>sum("")0>>>sum("",[])[]>>>sum("",{}){}为了弄清楚这里发生了什么,我们需要检查sum函数的签名:sum(iterable,/,start=0)sum从左到右对iterable的项目求和并返回总数。Iterable一般是一个数字,起始值不允许是字符串。在上述所有情况下,空字符串都被视为空序列,因此sum将简单地返回起始参数作为总结果。在第一种情况下它默认为零,对于第二种和第三种情况它意味着空列表和字典作为开始参数传入。7.意外属性>>>sum([...el.imag...forelin[...0,5,10e9,float('inf'),float('nan')...]。..])0.0上面的代码有一个imag属性,但我们根本没有定义它,它运行没有错误。这是怎么回事?这是因为Python中的所有数值类型(int、real、float)都继承自基对象类,它们都支持real和imag属性,分别返回实部和虚部。这也包括Infinity和NaN。8、输出负数倍数的字符串>>>"这是一个很长的字符串"*(-1)''>>>正确结果为'',所有负数倍数的字符串都视为0次,返回''。9、你见过负数0.0max(-0.0,0.0)吗?为什么会这样?有两个原因。负零和零在Python中被认为是相等的。max的逻辑是如果有多个maxima,返回遇到的第一个。所以max函数返回第一次出现的零,它恰好是负数。10.违反数学规则>>>x=(1<<53)+1>>>x+1.0>xFalse正确结果为False,违反数学规则。为什么?这种违反直觉的行为归因于三件事:长算术、浮点精度限制和数字比较。Python可以支持非常大的整数,如果隐式超出限制则切换计算模式,但Python中的浮点精度是有限的。2?3+1=9007199254740993是不能完全表示为Python浮点数的最小整数。因此,为了执行加1.0,Python将9007199254740993转换为浮点数,将其四舍五入为Python可以表示的9007199254740992.0,然后将其加上1.0,但由于相同的表示限制,它将其设置回9007199254740992.0:>>>float(9007199254740993)9007199254740992.0>>>9007199254740992.0+1.09007199254740992.0>>>此外,Python在将float与int进行比较时不会抛出错误,也不会尝试将两个操作数转换为相同的类型。相反,他们比较实际值。因为9007199254740992.0小于9007199254740993,Python返回False。