今天是一系列的小问题的集合哦
- 1、类继承+__class__方法
问题:有如下的一段代码,问如何使用对象obj调用A的show方法
答:obj是类B的一个实例对象,直接调用肯定调用的是类B的show方法。可以使用__class__方法来修改obj的类型,改为A类型,此时obj就变成了类A的一个实例对象,就可以调用A的show方法了,代码及结果如下
class A(object):
def show(self):
print('this is the A show!')
class B(object):
def show(self):
print('this is the B show!')
obj = B()
obj.show()
obj.__class__ = A
obj.show()
this is the B show!
this is the A show!
- 2、call(对象像函数一样调用)
问题:为了让下面这段代码运行,需要增加哪些代码?
答:看题目中的三个调用,首先a1=A(10,20)为定义一个类A的实例,a1.myprint()为类实例对象调用类内的方法,这两个都是没有问题的,而第三个是直接将实例当成一个函数在用,那需要实现一个__call__方法,该方法的功能类似于在类中重载 () 运算符,使得类实例对象可以像调用普通函数那样,以“对象名()”的形式使用。代码如下
class A(object):
def __init__(self, a, b):
self.__a = a
self.__b = b
def myprint(self):
print('this is print!')
def __call__(self, n):
print(n + self.__a + self.__b)
a1 = A(10, 20)
a1.myprint()
a1(80)
this is print!
110
- 3、__new__和__init__区别
问题:下面这段代码输出什么?
答:首先要懂__init__与__new__的差别,__new__是构造方法也就是创建一个实例,__init__是初始化一个实例,初始化一个已经创建的实例,也就是说,调用先后__new__在__init__前;同时注意,类A的构造方法中当a<=10时创建的是一个类B的实例,super(A, self).xxx()是调用A的父类的一种方法,此时生成的就是一个类A的实例。所以结果如下
- 4、列表推导式、字典推导式、集合推导式
问题:下面这段代码输出什么
答:本题考察的是三类推导式:列表推导式、字典推导式、集合推导式。
**列表推导式:**就是对一个可迭代对象中每个元素做相同的操作返回一个列表,并不会直接返回,需要赋值给一个变量,格式为:用中括号括起来,中间用for语句,后面跟if语句用作判读,满足条件的传到for语句前面用作构建先的列表
**字典推导式:**和列表推导式类似,就是把中括号换成大括号
**集合推导式:**和列表推导式类似,也是使用大括号,区别在于它是一个集合,无序无重复
代码结果如下:
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)
dic2 = {x: 'item' + str(x**2) for x in (2, 4, 6)}
print(dic2)
set1 = {x for x in 'hello world' if x not in 'low level'}
print(set1)
[3, 4]
[6, 8]
{2: 4, 4: 16, 6: 36}
{2: 'item4', 4: 'item16', 6: 'item36'}
{'r', 'h', 'd'}
- 5、全局变量与局部变量的作用范围及global关键字
问题:下面这段代码输出什么
答:上图中num为全局变量,作用域从定义完到代码结束,但是如果想要在某函数中修改全局变量的值时就变为局部变量了,作用域在函数内,所以即便在f1函数内的修改了局部变量num的值,也并没有修改全局变量的值,如果想要在函数中修改全局变量的值,只需要加上global关键字来声明全局变量然后就可以修改了,看如下代码
num = 9
def f1():
num = 20
def f2():
print(num)
def f3():
global num
num = 30
def f4():
num = num + 1 # 这里会报错说num没有被定义,因为不使用global关键词标识也不能使用全局变量的
def f5():
global num
num = num + 1
if __name__ == "__main__":
f2() # 第一次打印全局变量(对应下面第一个打印结果,后面类似)
f1() # 在函数内尝试进行全局变量的修改
f2() # 第二次打印全局变量
f3() # 使用global关键词修改全局变量
f2() # 第三次打印全局变量
num = 100 # if __name__ == "__main__"其实就是一个if语句,也算是在全局的作用范围内,
# 所以在这里用global声明也能对全局变量进行修改
f2() # 第四次打印全局变量
9
9
30
100
- 6、交换两个变量的值
问题:一行代码交换两个变量值
a = 8
b = 9
答:一行代码修改两个变量值,直接用元组来实现,如下面代码所示,其中代码右边为元组装包,左边为元组拆包
(a, b) = (b, a) 或 a, b = b, a
- 7、__getattr__方法的功能与使用
答:当在实例及其类的__dict__属性里找不到某属性或函数就会调用__getattr__方法,
8、包管理
问题:一个包里有三个模块,mod1.py , mod2.py , mod3.py ,但使用 from demopack import * 导入模块时,如何保证只有 mod1 、 mod3 被导入了。
答:在当前文件夹内增加__init__.py文件,写入
all = [‘mod1’, ‘mod3’]
分析:__init_.py文件为把文件夹变为一个python模块包,我们在导入一个包时其实就是导入了这个包的__init_.py文件,在文件内我们可以把一些我们依赖的模块全部导入,同时可以利用__init__.py文件的__all__变量来引入我们需要导入的文件
本文参考:
https://www.cnblogs.com/dion-90/articles/8401048.html
http://v2ee.cn/article?id=181