百度大牛总结十条Python面试题陷阱

问题1:请问如何修改以下Python代码,使下面的代码调用类A的show方法?

[python] view plain copy
print ?
  1. class A(object):  
  2.     def show(self):  
  3.         print(‘base show’)  
  4.   
  5. class B(A):  
  6.     def show(self):  
  7.         print(‘derived show’)  
  8.   
  9. obj = B()  
  10. obj.show()  
class A(object):
    def show(self):
        print('base show')

class B(A):
    def show(self):
        print('derived show')

obj = B()
obj.show()

答:题目问的是调用类A的show方法,不单单只是显示A中的show的内容,所以要通过class方法指定到A的类对象即可:

[python] view plain copy
print ?
  1. obj.__class__ = A  
  2. obj.show()  
obj.__class__ = A
obj.show()

问题2:请问如何修改以下Python代码,使得代码能够运行?

[python] view plain copy
print ?
  1. class A(object):  
  2.     def __init__(self, a, b):  
  3.         self.__a = a  
  4.         self.__b = b  
  5.     def myprint(self):  
  6.         print(‘a=’self.__a, ‘b=’self.__b)  
  7.   
  8. a1 = A(1020)  
  9. a1.myprint()  
  10.   
  11. a1(80)  
class A(object):
    def __init__(self, a, b):
        self.__a = a
        self.__b = b
    def myprint(self):
        print('a=', self.__a, 'b=', self.__b)

a1 = A(10, 20)
a1.myprint()

a1(80)

答:该程序运行报了一个错误

[python] view plain copy
print ?
  1. Traceback (most recent call last):  
  2. (’a=’10‘b=’20)  
  3.   File ”C:/Users/Lee/PycharmProjects/print/exeses.py”, line 11in <module>  
  4.     a1(80)  
  5. TypeError: ’A’ object is not callable  
Traceback (most recent call last):
('a=', 10, 'b=', 20)
  File "C:/Users/Lee/PycharmProjects/print/exeses.py", line 11, in <module>
    a1(80)
TypeError: 'A' object is not callable

这个错误的大致意思是将A类当成了一个方法来进行调用是不可行的。为了让对象实例能被直接调用,需要实现call方法。

[python] view plain copy
print ?
  1. #-*- coding:utf-8 -*-  
  2. class A(object):  
  3.     def __init__(self, a, b):  
  4.         self.__a = a  
  5.         self.__b = b  
  6.     def myprint(self):  
  7.         print(‘a=’self.__a, ‘b=’self.__b)  
  8.     def __call__(self, num):#num传入  
  9.         print(‘call:’, num + self.__a)#随意让num做一些事  
  10.   
  11. a1 = A(1020)  
  12. a1.myprint()  
  13.   
  14. a1(80)  
#-*- coding:utf-8 -*-
class A(object):
    def __init__(self, a, b):
        self.__a = a
        self.__b = b
    def myprint(self):
        print('a=', self.__a, 'b=', self.__b)
    def __call__(self, num):#num传入
        print('call:', num + self.__a)#随意让num做一些事

a1 = A(10, 20)
a1.myprint()

a1(80)

结果

[python] view plain copy
print ?
  1. (‘a=’10‘b=’20)  
  2. (’call:’90)  
('a=', 10, 'b=', 20)
('call:', 90)

问题3:下面这段代码的输出是什么?

[python] view plain copy
print ?
  1. class B(object):  
  2.     def fn(self):  
  3.         print(‘B fn’)  
  4.     def __init__(self):  
  5.         print(‘B INIT’)  
  6.           
  7. class A(object):  
  8.     def fn(self):  
  9.         print(‘A fn’)  
  10.   
  11.     def __new__(cls, a):  
  12.         print(‘NEW’, a)  
  13.         if a > 10:  
  14.             return super(A, cls).__new__(cls)  
  15.         return B()  
  16.   
  17.     def __init__(self, a):  
  18.         print(‘INIT’, a)  
  19.   
  20. a1 = A(5)  
  21. a1.fn()  
  22. a2 = A(20)  
  23. a2.fn()  
class B(object):
    def fn(self):
        print('B fn')
    def __init__(self):
        print('B INIT')

class A(object):
    def fn(self):
        print('A fn')

    def __new__(cls, a):
        print('NEW', a)
        if a > 10:
            return super(A, cls).__new__(cls)
        return B()

    def __init__(self, a):
        print('INIT', a)

a1 = A(5)
a1.fn()
a2 = A(20)
a2.fn()
答:该题的关键点在于__new__方法。 __init__其实不是实例化一个类的时候第一个被调用 的方法。当使用 a1 = A(5) 这样的表达式来实例化一个类时,最先被调用的方法 其实是 __new__ 方法。所以很自然的,第一行输出为NEW 5.接着判断a是否大于10,此时a = 5,所以执行return B(),进入B类中运行;所以第二行和第三行是B类实例的调用B INIT, B fn。随后新建一个a2的类实例,将a = 20传入A类,先执行__new__,所以第四行是NEW 20,此时a大于了10,执行
[python] view plain copy
print ?
  1. return super(A, cls).__new__(cls)  
return super(A, cls).__new__(cls)

大致的意思是得到当前类的实例(如果要得到当前类的实例,应当在当前类中的__new__()方法语句中调用当前类的父类 的__new__()方法)

所以还是实例还是在A中,第五行输出INIT 20,接着调用A类中的fn方法,输出A fn。最终结果

[python] view plain copy
print ?
  1. (‘NEW’5)  
  2. B INIT  
  3. B fn  
  4. (’NEW’20)  
  5. (’INIT’20)  
  6. A fn  
('NEW', 5)
B INIT
B fn
('NEW', 20)
('INIT', 20)
A fn

问题4:下面这段代码输出什么?

[python] view plain copy
print ?
  1. ls = [1234]  
  2. list1 = [i for i in ls if i > 2]  
  3. print(list1)  
  4.   
  5. list2 = [i * 2 for i in ls if i > 2]  
  6. print(list2)  
  7.   
  8. dic1 = {x: x ** 2 for x in (246)}  
  9. print(dic1)  
  10.   
  11. set1 = {x for x in ‘hello world’ if x not in ‘low level’}  
  12. print(set1)  
ls = [1, 2, 3, 4]
list1 = [i for i in ls if i > 2]
print(list1)

list2 = [i * 2 for i in ls if i > 2]
print(list2)

dic1 = {x: x ** 2 for x in (2, 4, 6)}
print(dic1)

set1 = {x for x in 'hello world' if x not in 'low level'}
print(set1)

答:该题考查列表解析和字典还有集合的生成方法。输出如下:

[python] view plain copy
print ?
  1. [34]  
  2. [68]  
  3. {24416636}  
  4. set([’h’‘r’‘d’])  
[3, 4]
[6, 8]
{2: 4, 4: 16, 6: 36}
set(['h', 'r', 'd'])

问题5:下面这段代码输出什么?

[python] view plain copy
print ?
  1. num = 9  
  2.   
  3. def f1():  
  4.     num = 20  
  5.   
  6. def f2():  
  7.     print(num)  
  8.   
  9. f2()  
  10. f1()  
  11. f2()  
num = 9

def f1():
    num = 20

def f2():
    print(num)

f2()
f1()
f2()

答:该题考查全局变量和局部变量的知识。先定义一个num = 9的全局变量,接着在f1中定义了num = 20.由于局部变量只能在当前定义的函数或者类中被调用,而全局变量可以在任何函数或者类中被调用,前提是没有被同名的局部变量所覆盖。所以该题的答案很明显了,调用f2,print num 应该是全局变量的num = 9,f1中的num  f2函数无法调用;接着调用f1,没有print,所以无输出;最后再一次调用f2,f1中的num = 20 并不能直接改变全局变量的值,所以输出9.要想在局部变量中修改全局变量的值,需要使用global

[python] view plain copy
print ?
  1. num = 9  
  2.   
  3. def f1():  
  4.     global num  
  5.     num = 20  
  6.   
  7. def f2():  
  8.     print(num)  
  9.   
  10. f2()  
  11. f1()  
  12. f2()  
num = 9

def f1():
    global num
    num = 20

def f2():
    print(num)

f2()
f1()
f2()

这样num就被修改为了20

[python] view plain copy
print ?
  1. 9  
  2. 20  
9
20

问题6:如何使用一行代码交换两个变量的值?

[python] view plain copy
print ?
  1. a = 8  
  2. b = 9  
a = 8
b = 9

答:

[python] view plain copy
print ?
  1. (a, b) = (b, a)  
(a, b) = (b, a)

问题7:如何添加代码,使得没有定义的方法都调用mydefault方法?

[python] view plain copy
print ?
  1. class A(object):  
  2.     def __init__(self, a, b):  
  3.         self.a1 = a  
  4.         self.b1 = b  
  5.         print(‘init’)  
  6.           
  7.     def mydefault(self):  
  8.         print(‘default’)  
  9.           
  10. a1 = A(1020)  
  11. a1.fn1()  
  12. a1.fn2()  
  13. a1.fn3()  
class A(object):
    def __init__(self, a, b):
        self.a1 = a
        self.b1 = b
        print('init')

    def mydefault(self):
        print('default')

a1 = A(10, 20)
a1.fn1()
a1.fn2()
a1.fn3()
答:可以使用__getattr__方法解决这个问题, __getattr__函数的作用: 如果属性查找(attribute lookup)在实例以及对应的类中(通过__dict__)失败, 那么会调用到类的__getattr__函数, 如果没有定义这个函数,那么抛出AttributeError异常。由此可见,__getattr__一定是作用于属性查找的最后一步,兜底。
[python] view plain copy
print ?
  1. class A(object):  
  2.     def __init__(self, a, b):  
  3.         self.a1 = a  
  4.         self.b1 = b  
  5.         print(‘init’)  
  6.   
  7.     def mydefault(self, *args):  
  8.         print(‘default’)  
  9.       
  10.     def __getattr__(self, item):  
  11.         return self.mydefault()#指向mydefault方法  
  12.           
  13.   
  14. a1 = A(1020)  
  15. a1.fn1()  
  16. a1.fn2()  
  17. a1.fn3()  
class A(object):
    def __init__(self, a, b):
        self.a1 = a
        self.b1 = b
        print('init')

    def mydefault(self, *args):
        print('default')

    def __getattr__(self, item):
        return self.mydefault()#指向mydefault方法


a1 = A(10, 20)
a1.fn1()
a1.fn2()
a1.fn3()
这样就就不会触发异常了。还可以给mydefault方法增加一个*args不定参数来兼容。

问题8:一个包里有三个模块,mod1,py, mod2.py, mod3.py, 但使用from demopack import * 导入模块时,如何保证只有mod1, mod3被导入了?

答:在包中init.py文件,并在文件中增加:

[python] view plain copy
print ?
  1. __all__ = [‘mod1’‘mod3’]  
__all__ = ['mod1', 'mod3']

python模块中的__all__w属性,可用于模块导入时限制,此时被导入模块若定义了__all__属性,则只有__all__内指定的属性、方法、类可被导入。

若没定义,则导入模块内的所有公有属性,方法和类 。

问题9:写一个函数,接收整数参数n,返回一个函数,函数返回n和参数的积。

[python] view plain copy
print ?
  1. def f1(n):  
  2.     def f2(x):  
  3.         return n * x  
  4.     return f2  
  5.   
  6. num = f1(3)  
  7. print(num(9))  
def f1(n):
    def f2(x):
        return n * x
    return f2

num = f1(3)
print(num(9))

问题10:请问下面的代码有什么隐患?

[python] view plain copy
print ?
  1. def strtest1(num):  
  2.     str = ’first’  
  3.     for i in range(num):  
  4.         str += ’x’  
  5.     return str  
def strtest1(num):
    str = 'first'
    for i in range(num):
        str += 'x'
    return str
答:由于变量str是个不可变对象,每次迭代,Python都会生成新的str对象来存储新的字符串,num越大,创建的str对象越多,内存消耗越大。

转自:https://blog.csdn.net/qq_41805514/article/details/80556807

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值