(多选)1. python中__new__和__init__的说法正确的有( ABCD )
A. __new__是一个静态方法,而__init__是一个实例方法
B. __new__方法会返回一个创建的实例,而__init__什么都不返回
C. 只有在__new__返回一个cls的实例时,后面的__init__才能被调用
D. 当创建一个新实例时调用__new__,初始化一个实例时用__init__
解析:
在 Python 中,__init__和__new__是两个特殊的方法,用于创建和初始化对象。__new__方法用于创建对象,并返回一个实例化的对象,它是一个静态方法。而 init 方法用于对从 new 方法返回的对象进行初始化,它是一个实例方法。
__new__方法是在对象被创建之前调用的,所以它可以没有返回值,也可以返回其他类型的对象。而 init 方法是在对象创建后调用的,用于初始化对象的属性,并且它必须返回None。
在 Python 中,对象的创建过程包括 new 方法和 init 方法两个步骤。new 方法负责创建对象,init 方法负责初始化对象的属性。通常情况下,我们不需要手动调用 new 方法,Python 会自动调用它来创建对象。而 init 方法则需要重写,用于初始化对象的属性。
总的来说,new 方法是用于创建对象的,而 init 方法是用于初始化对象的属性。它们的区别在于 new 方法是一个静态方法,用于创建对象,在对象被创建之前调用;而 init 方法是一个实例方法,用于初始化对象的属性,在对象被创建之后调用。
class MyClass:
def __new__(cls):
print("Object is created")
return super().__new__(cls)
def __init__(self):
print("Object is initialized")
my_obj = MyClass() # 输出 "Object is created" 和 "Object is initialized"
在上面的代码中,我们重写了 new 方法和 init 方法,并通过调用 super() 函数来调用父类的方法。当我们创建 MyClass 实例时,会先调用 new 方法,输出 "Object is created",然后再调用 init 方法,输出 "Object is initialized"。
(单选)2.为输出一个字典dic = {‘a’:1,'b':2},下列选项中,做法错误的是( B )
A
lis1 = ['a','b']
lis2 = [1,2]
dic = dict(zip(lis1,lis2))
print(dic)
B
tup = ('a','b')
lis = [1,2]
dic = {tup:lis}
print(dic)
C
dic = dict(a=1,b=2)
print(dic)
D
lis = ['a','b']
dic = dict.fromkeys(lis)
dic['a'] = 1
dic['b'] = 2
print(dic)
解析:
A选项中zip()映射函数将两个列表的元素打包为元组,返回一个zip对象,再使用dict()转换为字典,得到结果为{'a':1,'b':2};
B选项结果为{('a','b')}:[1,2]},字典的键为元组('a','b'),值为列表[1,2];
C选项中dict()函数使用关键字参数构建字典,结果为{'a':1,'b':2};
D选项中fromkeys()方法传入列表[‘a','b']作为字典的键名,再依次为其赋值,得到字典{'a':1,'b':2}
(单选) 执行以下程序,输出结果为( C )
def outer(fn):
print('outer')
def inner():
print('inner')
return fn
return inner
@outer
def fun():
print('fun')
A. outer
B. inner
C. fun
D. 因为没有调用任何函数,所以没有输出结果
解析:
这段代码看上去函数是没有被调用的,但为什么会有输出呢,这涉及到装饰器的知识点。
装饰器的一个关键特性是,它在被装饰函数定义后被立即执行,因此运行装饰函数outer,输出结果为outer,内部函数inner没有调用,不会输出任何结果,被装饰函数同样也不会运行。
如果去掉装饰函数定义,即去掉 @outer 这行,这段代码就不会有任何输出,但如果加上@outer
则会运行装饰函数。
如果加上函数调用fun(),输出如下所示。
def outer(fn):
print('outer')
def inner():
print('inner')
return fn
return inner
@outer
def fun():
print('fun')
if __name__ == '__main__':
fun()
'''
输出-> outer
inner
'''
(单选)执行以下程序,输出结果为( B )
a = [['1','2'] for i in range(2)]
b = [['1','2']]*2
a[0][1] = '3'
b[0][0] = '4'
print(a,b)
A. [['1', '3'], ['1', '3']] [['4', '2'], ['4', '2']]
B. [['1', '3'], ['1', '2']] [['4', '2'], ['4', '2']]
C. [['1', '3'], ['1', '2']] [['4', '2'], ['1', '2']]
D. [['1', '3'], ['1', '3']] [['4', '2'], ['1', '2']]
解析:
使用列表生成式生成的列表a=[['1', '2'], ['1', '2']],列表的两个元素虽然也是列表,但它们是不同的引用,修改其中的一个列表元素不影响另一个列表元素;而使用*生成的列表b=[['1', '2'], ['1', '2']] ,列表的两个列表元素指向同一个地址,修改时互相影响。
(单选)有一段python的编码程序如下,请问经过该编码的字符串的解码顺序是( D )
1 |
|
A. gbk utf16 url解码
B. gbk url解码 utf16
C. url解码 gbk utf16
D. url解码 utf16 gbk
解析:
字符串编译的过程:gbk==>unicode==>utf16==>url解码
字符串解码顺序为:url解码==>utf16==>unicode==>gbk
(单选)运行以下代码的输出为( D )
1 2 3 4 5 6 7 |
|
A. Person
B. getAge
C. usr.lib.python.person
D. __main__
解析:
__name__
在Python中是一个特殊的变量,被用来表示当前模块的名称。当一个模块被直接运行时,__name__
被设置为__main__
。也就是说,如果一个.py文件被直接运行,那么这个文件中的__name__
就是__main__
,否则就是该模块的名称。例如,假设有两个Python文件,一个名为module1.py
,一个名为module2.py
,module1.py
中包含了一个函数test()
,可以在module2.py
中通过导入方式使用。当module1.py
被直接运行时,__name__
的值为__main__
,这时候可以执行test()
函数;但是当module1.py
被导入至module2.py
中时,__name__
的值为module1
,此时不能直接执行test()
函数,因为test()
函数只有在module1.py
被直接运行时才会执行。
在Python3中。下列程序运行结果说明正确的是( D )
1 2 |
|
A. 'ABCD12EFG'
B. 'Abc12efg'
C. 语法错误
D. 'Abcd12Efg'
解析:
在Python3中,upper() 表示将字符小写转换为大写,title方法将字符串内每个连续字母的首字母大写,其余小写,数字后面的字母被title当成首字母大写了。
因为这两个都是返回一个可迭代值,不会改变原来的值 所以只有title()生效
根据以下程序,下列选项中,说法正确的是( C )
class Foo():
def __init__(self):
pass
def __getitem__(self,pos):
return range(0,30,10)[pos]
foo = Foo()
A. foo对象表现得像个序列
B. 可以使用len(foo)来查看对象foo的元素个数
C. 可以使用for i in foo:print(i)来遍历foo的元素
D. 不能使用foo[0]来访问对象foo的第一个元素
解析:
若要表现像个序列,必须满足序列的两个方法:__len__和__getitem__,由于Foo类中没有实现__len__,因此不满足序列协议,foo对象不像序列,A错误;
foo对象没有定义__len__方法,不能使用它来查看对象个数,B错误;
对对象的迭代需要调用__iter__,如果没有定义该方法,python会调用__getitem__(),让迭代和in运算符可用,因此foo是可迭代的,C正确;
根据索引访问对象元素,会调用__getitem__(),因此D错误。
以下这段代码的输出结果为( D )
1 2 3 4 5 6 7 |
|
A. Hello World!
B. 一个 shape = (5,10) 的随机整数矩阵
C. 一个 shape = (5,10) 的 one-hot 矩阵
D. 一个 shape = (10,5) 的 one-hot 矩阵
解析:
a = np.repeat(np.arange(5).reshape([1,-1]),10,axis = 0)+10.0
np.repeat(a,b)将a重复b次,np.arange(5).reshape([1,-1])创建等差数组,1行,列未知
即【0,1,2,3,4】按行重复10次,广播每一个值加10
b = np.random.randint(5, size= a.shape)
生成[0,5)随机矩阵,大小和矩阵a相同
c = np.argmin(a*b, axis=1)
矩阵a和b乘积,返回每行最小值位置
b = np.zeros(a.shape)
与矩阵a相同大小的全零矩阵
b[np.arange(b.shape[0]), c] = 1
b中所有c返回位置置为1
以下程序输出为( A )
info = {'name':'班长', 'id':100, 'sex':'f', 'address':'北京'}
age = info.get('age')
print(age)
age=info.get('age',18)
print(age)
A. None 18
B. None None
C. 编译错误
D. 运行错误
解析:
dict.get(key, default=None)
key -- 字典中要查找的键。 default -- 如果指定键的值不存在时,返回该默认值值;
对于Python类中单下划线_foo、双下划线__foo与__foo__的成员,下列说法正确的是( --ABC )
A. _foo 不能直接用于’from module import *’
B. __foo解析器用_classname__foo来代替这个名字,以区别和其他类相同的命名
C. __foo__代表python里特殊方法专用的标识
D. __foo 可以直接用于’from module import *’
解析:
在Python中,有三种不同类型的命名方式:以单下划线(_)开头、以双下划线()开头和以双下划线()开头和结尾。它们分别表示不同的含义。
-
以单下划线(_)开头的变量表示这是一个私有变量或方法,虽然不是真正的私有,但是建议不要在类外部直接访问这些变量和方法,以免程序出现问题。
-
以双下划线(__)开头的变量表示这是一个私有变量或方法,真正的私有变量或方法,无法从外部直接访问。
-
以双下划线(__)开头和结尾的变量是特殊变量,可以被直接调用,也可以被子类覆盖。例如,
__init__
和__call__
等方法是特殊方法,可以在类中直接使用。
class MyClass:
def __init__(self):
self.__private_var = "I am a private variable"
self._protected_var = "I am a protected variable"
self.public_var = "I am a public variable"
def __private_method(self):
print("This is a private method")
def _protected_method(self):
print("This is a protected method")
def public_method(self):
print("This is a public method")
def call_private(self):
self.__private_method()
my_object = MyClass()
# 私有变量
print(my_object._MyClass__private_var) # 不建议直接访问私有属性
# print(my_object.__private_var) # 会出现AttributeError
# 受保护的变量
print(my_object._protected_var)
# 公有变量
print(my_object.public_var)
# 调用不同类型的方法
my_object.call_private() # 可以通过特殊方式调用私有方法
my_object._protected_method() # 可以通过下划线调用受保护方法
my_object.public_method() # 直接调用公有方法
上述代码中,__private_var
和 __private_method
是私有变量和方法,_protected_var
和 _protected_method
是受保护的变量和方法,public_var
和 public_method
是公有的变量和方法。在访问私有变量时,可以通过前缀 _MyClass
来访问,但是不建议直接访问私有变量和方法,因为如果类实现发生了变化,可能会导致程序出现问题。
以下代码运行结果为( A )
1 2 3 |
|
A. [1,3,5]
B. [1,2,1,0,1]
C. [1, 2, 3, 4, 5]
D. [1,2,3]
解析:
filter(function, iterable)
filter函数是python中的高阶函数
第一个参数function是一个筛选函数, 第二个参数是一个可迭代对象, 返回的是一个生成器类型, 可以通过next获取值。
filter()把传入的function依次作用于iterable的每个元素, 满足条件的返回true, 不满足条件的返回false, 通过true还是false决定将该元素丢弃还是保留.
所以对2和4取余为0 -> 舍弃
1,3,5取余为1为真 -> 保留;
执行以下程序,结果输出为( A )
a = [1]
b = 2
c = 1
def fn(lis,obj):
lis.append(b)
obj = obj + 1
return lis,obj
fn(a,c)
print(fn(a,c))
A. ([1, 2, 2], 2)
B. ([1, 2, 2], 3)
C. ([1, 2], 2)
D. ([1, 2], 3)
解析:
a为可变类型,c为不可变类型
fn(a,c):调用了一次fn函数,这时候a变成了[1,2],c还是1,因为函数虽然返回了obj,但是没有赋值,出了函数之后c还是全局变量的那个c,但是函数中lis列表为可变对象,调用后发生了改变;
print(fn(a,c)):又调用了一次fn函数,过程同上,但是打印的时候打印的是函数的返回值,也就是此时的形参lis和obj的值,而此时lis是[1,2,2],而obj是2。
当一个嵌套函数在其外部区域引用了一个值时,该嵌套函数就是一个闭包,以下代码输出值为( D )
1 2 3 4 5 6 |
|
A. 10
B. 12
C. 14
D. 16
解析:
adder(5) -> 返回了 wrapper ,且x=5
adder5 = adder(5) -> adder5是对wrapper的引用 此时x等于5
adder5(6) -> 相当于 wrapper(6) = 5+6=11 所以 adder5(6) =11 ,同理adder5(7)=12
adder5(adder5(6)) = adder5(11) = wrapper(11) =5+11=16
对于以下代码,描述正确的是( D )
list = ['1', '2', '3', '4', '5']
print list[10:]
A. 导致 IndexError
B. 输出['1', '2', '3', '4', '5']
C. 编译错误
D. 输出[]
解析:
切片不受内建类型的限制,若超出则返回一个空序列;
如果是索引访问,会导致IndexError;
为了以下程序能够正常运行,①处可以填入的语句是( C )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
A
property
B
setter
C
color.setter
D
setter.color
解析:
python中的@*.setter装饰器可以总结为两个作用:
- 对要存入的数据进行预处理
- 设置可读属性(不可修改)
@preperty 装饰器使得类有了一个方法同名属性color
通过 @color.setter @color.getter 这类装饰器装饰的方法则可以被调用,对color属性进行修改
在Python3中,下列程序返回的结果为( B )
1 2 |
|
A. None
B. -1
C. 报错
D. 空
解析:
在Python3中,str.find(str, beg=0, end=len(string)) 检测字符串中是否包含子字符串 str ,如果指定 beg(开始) 和 end(结束) 范围,则检查是否包含在指定范围内,如果包含子字符串返回开始的索引值,否则返回-1
根据以下程序,下列选项中,说法正确的是( D )
class Vector:
__slots__='x','y'
def __init__(self):
pass
class Vector3d(Vector):
__slots__='x','z'
def __init__(self):
pass
vector = Vector()
vector3d = Vector3d()
A. 若子类没有定义__slots__属性,则子类可以继承父类的__slots__属性
B. Vector类的实例对象vector会自动获得实例属性x和y
C. Vector3d类的实例对象vector3d最多只能允许属性x和z
D. Vector3d类的实例对象vector3d最多只能允许属性x、y和z
解析:
__slots__属性用来限制实例对象的属性,实例对象的实例属性最多只能在__slots__属性值的范围内。如果子类没有定义__slots__属性,则不会继承父类的__slots__属性,如果子类定义了__slots__属性,则子类对象允许的实例属性包括子类的__slots__加上父类的__slots_。
已知a = [1, 2, 3]和b = [1, 2, 4],那么id(a[1])==id(b[1])的执行结果 ( A )
A. True
B. False
解析:
id(object)是python的一个函数用于返回object的内存地址。但值得注意的是,python 为了提高内存利用效率会对一些简单的对象(如数值较小的int型对象,字符串等)采用重用对象内存的办法.
在python3中,下列程序结果为( C )
1 2 3 |
|
A. 1,[]
B. 1,{}
C. 1,报错
D. 1,None
解析
py3 访问不存在的索引或key:
字典:key访问报KeyError,get访问默认返回None
列表、元组、字符串:IndexError
py3 切片越界(索引为自然数情况):
列表: start越界:返回[] 空列表
end越界:返回原列表浅拷贝
start、end均越界:[] 空列表
元组: start越界:返回() 空元组
end越界:返回原元组
start、end均越界:() 空元组
字符串: start越界:返回'' 空字符
end越界:返回原字符串
start、end均越界:'' 空字符
执行下列选项中的程序,输出结果为False的是( B )
A
t1 = (1,2,3)
t2 = t1[:]
print(t1 is t2)
B
lis1 = [1,2,3]
lis2 = lis1[:]
print(id(lis1)==id(lis2))
C
s1 = '123'
s2 = '123'
print(s1 is s2)
D
a = 123
b = 123
print(id(a) == id(b))
解析:
由数字,字符和下划线组成的短字符串以及[-5,256]内的整数存在内存驻留,将其赋值给多个不同的对象时,内存中只有一个副本,多个对象共享该副本,故CD选项结果均为True;
对于A选项,元组的[:]并不会创建副本,而是返回同一个对象的引用,所以t1和t2的id值均一样,结果为True;
对于B选项,列表的[:]会创建副本,其id值发生改变,结果为False。
在Python3中,程序运行结果为( C )
1 2 3 4 |
|
A. [2,3,4,5,6]
B. [1,2,3,4,5,6,[7,8,9]]
C. [1,2,3,4,5,6,7,8,9]
D. [2,3,4,5,6,7,8,9]
解析:
lists = [1, 1, 2, 3, 4, 5, 6]
lists.remove(1)
lists.append([7,8,9])
print(lists)
#输出-> [1, 2, 3, 4, 5, 6, [7, 8, 9]]
append函数将这个对象加入列表末尾
lists = [1, 1, 2, 3, 4, 5, 6]
lists.remove(1)
lists.extend([7,8,9])
print(lists)
#输出-> [1, 2, 3, 4, 5, 6, 7, 8, 9]
extend函数将这个对象的元素加入列表末尾
当使用import导入模块时,按python查找模块的不同顺序可划分为以下几种,其中查找顺序正确的一组是( C )
①环境变量中的PYTHONPATH
②内建模块
③python安装路径
④当前路径,即执行Python脚本文件所在的路径
A. ①④②③
B. ②①④③
C. ②④①③
D. ①②③④
解析:
当使用 import 导入模块时,Python 解释器会按照以下顺序搜索模块:
- 首先导入内建模块进行判断。
- 其次在当前目录下查找模块,如果找到直接载入模块。
- 如果当前目录下没有找到,Python 会在环境变量 PYTHONPATH 中指定的目录下查找。
- 如果 PYTHONPATH 中的路径仍然没有找到,则会搜索 Python 安装时的默认路径。
- 如果所有路径都没有找到对应的模块,则会抛出 ImportError 异常。
在python3运行环境下,执行以下选项中的代码,其输出结果不为[2,4,6,8,10]的是( D )
A
a = [1,2,3,4,5,6,7,8,9,10]
print(a[1::2])
B
a = [1,2,3,4,5,6,7,8,9,10]
lis = []
for i in a:
if i % 2 == 0:
lis.append(i)
print(lis)
C
a = [1,2,3,4,5,6,7,8,9,10]
print(list(filter(lambda x:x % 2 ==0,a)))
D
a = [1,2,3,4,5,6,7,8,9,10]
def is_odd(n):
return n % 2 == 0
print(list(filter(is_odd(),a)))
解析:
D选项会抛出一个缺少位置参数的异常,实际上这里调用的是函数本身,是整个函数体,不需要等待函数执行完成,所以调用时不需要加小括号,正确的调用方式为print(list(filter(is_odd,a)))
A-> 表示从1开始,以步长为2开始取元素,最后取到[2,4,6,8,10];
B-> 遍历a列表把a的每个数取出来除以2余0的追加在新列表中,最后列表中有[2,4,6,8,10];
C-> lambda后面跟的是一个函数,计算x除以2是否余数等于0,用一个过滤器filter()留下偶数,迭代对象是a,最后转换成list输出,[2,4,6,8,10];
D-> is_odd,不带括号,调用整个函数本身,这里需要的就是函数本身;