Maison  >  Article  >  développement back-end  >  Questions de code qui doivent être testées lors des entretiens Python

Questions de code qui doivent être testées lors des entretiens Python

不言
不言avant
2019-02-23 10:25:204620parcourir

Questions de code qui doivent être testées lors des entretiens Python

Le contenu de cet article concerne les questions de code qui doivent être testées dans les entretiens python. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. pour vous.

Articles connexes recommandés  : " Résumé des questions d'entretien Python en 2020 (dernières) "

Question 1 : Quel sera le résultat du code suivant ? Donnez votre réponse et expliquez.

class Parent(object):
    x = 1
 
class Child1(Parent):
    pass
 
class Child2(Parent):
    pass
 
print Parent.x, Child1.x, Child2.x
Child1.x = 2
print Parent.x, Child1.x, Child2.x
Parent.x = 3
print Parent.x, Child1.x, Child2.x

La réponse est

1 1 1
1 2 1
3 2 3

Ce qui peut vous dérouter ou vous surprendre, c'est que la dernière ligne de sortie est 3 2 3 au lieu de 3 2 1. Pourquoi la modification de la valeur de Parent.x modifie-t-elle également la valeur de Child2.x, mais en même temps la valeur de Child1.x ne change pas ?

La clé de cette réponse est qu'en Python, les variables de classe sont traitées en interne comme des dictionnaires. Si le nom d'une variable n'est pas trouvé dans le dictionnaire de la classe courante, la classe ancêtre (telle que la classe parent) sera recherchée jusqu'à ce que le nom de la variable référencée soit trouvé (si le nom de la variable référencée n'est ni dans sa propre classe ni dans sa propre classe). dans la classe ancêtre), une exception AttributeError sera levée).

Ainsi, définir x = 1 dans une classe parent fait que la variable de classe X a une valeur de 1 dans les références à cette classe et à l'une de ses sous-classes. En effet, la sortie de la première instruction print est 1 1 1.

Par la suite, si l'une de ses sous-classes remplace la valeur (par exemple, nous exécutons l'instruction Child1.x = 2), alors la valeur n'est modifiée que dans la sous-classe. C'est pourquoi le résultat de la deuxième instruction print est 1 2 1.

Enfin, si la valeur est modifiée dans la classe parent (par exemple, nous exécutons l'instruction Parent.x = 3), ce changement affectera la valeur dans toute sous-classe qui ne remplace pas la valeur (dans cette La sous-classe concernée dans l'exemple est Child2). C'est pourquoi la troisième sortie d'impression est 3 2 3.

Question 2 : Quel sera le résultat du code suivant ? Dites-nous votre réponse et expliquez-la ?

def p1(x,y):
    print("%s/%s = %s" % (x, y, x/y))

def p2(x,y):
    print("%s//%s = %s" % (x, y, x//y))

p1(5,2)
p1(5.,2)
p2(5,2)
p2(5.,2.)
5/2 = 2
5.0/2.0=2.5
5/2=2
5/2=2

Réponse

Cette réponse dépend en fait si vous utilisez Python 2 ou Python 3.

En Python 3, la sortie souhaitée est :

5/2 = 2.5
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0

En Python 2, cependant, la sortie du code ci-dessus sera :

5/2 = 2
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0

Default , si les deux opérandes sont des entiers, Python 2 effectue automatiquement des calculs d'entiers. Par conséquent, 5/2 a une valeur de 2, tandis que 5./2 a une valeur de "2.5``.

Notez que, cependant, vous pouvez remplacer ce comportement dans Python 2 (par exemple pour obtenir ce que vous voulez en Python 3), en ajoutant l'import suivant :

from__future__ import pision
Notez également que l'opérateur "double tiret" (//) effectuera toujours une division entière quel que soit le type d'opérandes, c'est pourquoi 5.0//2.0 a une valeur de 2.0.

Remarque : dans Python 3, l'opérateur / effectue une division en virgule flottante et // effectue une division entière (c'est-à-dire que le quotient n'a pas de reste, tel que comme 10 / Le résultat de / 3 est 3, et le reste sera tronqué, tandis que le résultat de (-7) // 3 est -3. Cet algorithme est différent de nombreux autres langages de programmation. Il convient de noter que leur nombre entier. les opérations de division se déplaceront vers 0. La direction de la valeur. Dans Python 2, / est une division entière, qui est la même que l'opérateur // dans Python 3,)

Question 3 : Quoi le code suivant sera-t-il affiché ?

list = ['a', 'b', 'c', 'd', 'e']
print list[10:]

Réponse
Le code ci-dessus affichera [ ] et ne provoquera pas d'IndexError

Comme on le ferait s'attendre à essayer d'accéder à plus d'un index de liste. Les membres d'une valeur provoqueront une IndexError (comme l'accès à la liste [10] de la liste ci-dessus. Cependant, essayer d'accéder à une tranche d'une liste commençant à un index qui dépasse l'index). le nombre de membres de la liste ne provoquera pas d'IndexError et renverra simplement une liste vide

Un vilain petit problème est que cela provoque des bugs, et le problème est difficile à localiser car il ne génère pas d'erreur. runtime.

Problème 4 : Le résultat du code suivant : Quelle serait-elle ? Énoncez votre réponse et expliquez

def multipliers():
    return [lambda x : i * x for i in range(4)]

print [m(2) for m in multipliers()]

Comment modifieriez-vous la définition des multiplicateurs. produire le résultat souhaité

Réponse

La sortie du code ci-dessus est [6, 6, 6, 6] (au lieu de [0, 2, 4, 6]).

La raison en est la fermeture tardive de Python entraîne une liaison tardive, ce qui signifie que les variables dans la fermeture sont recherchées lorsque la fonction interne est appelée, le résultat est donc que. lorsqu'une fonction renvoyée par multiplicateurs() est appelée, à ce moment-là, la valeur est recherchée dans la portée environnante lorsqu'elle est appelée, quelle que soit la fonction renvoyée qui est appelée, la boucle for est terminée et la valeur finale de. i vaut 3, donc la valeur de chaque fonction renvoyée se multiplie. Les deux valent 3. Ainsi, si une valeur égale à 2 est passée dans le code ci-dessus, ils renverront une valeur de 6 (par exemple : 3 x 2).

(顺便说下,正如在 The Hitchhiker’s Guide to Python 中指出的,这里有一点普遍的误解,是关于 lambda 表达式的一些东西。一个 lambda 表达式创建的函数不是特殊的,和使用一个普通的 def 创建的函数展示的表现是一样的。)

这里有两种方法解决这个问题

最普遍的解决方案是创建一个闭包,通过使用默认参数立即绑定它的参数。例如:

def multipliers():
    return [lambda x, i=i : i * x for i in range(4)]

另外一个选择是,你可以使用 functools.partial 函数

from functools import partial
from operator import mul

def multipliers():
    return [partial(mul, i) for i in range(4)]

问题五:以下的代码的输出将是什么? 说出你的答案并解释?

def extendList(val, list=[]):
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

你将如何修改 extendList 的定义来产生期望的结果

以上代码的输出为:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

许多人会错误的认为 list1 应该等于 [10] 以及 list3 应该等于 [‘a’]。认为 list 的参数会在 extendList 每次被调用的时候会被设置成它的默认值 [ ]。

尽管如此,实际发生的事情是,新的默认列表仅仅只在函数被定义时创建一次。随后当 extendList 没有被指定的列表参数调用的时候,其使用的是同一个列表。这就是为什么当函数被定义的时候,表达式是用默认参数被计算,而不是它被调用的时候。

因此,list1 和 list3 是操作的相同的列表。而 "`list2是操作的它创建的独立的列表(通过传递它自己的空列表作为list"参数的值)。

extendList 函数的定义可以做如下修改,但,当没有新的 list 参数被指定的时候,会总是开始一个新列表,这更加可能是一直期望的行为。

def extendList(val, list=None):
    if list is None:
        list = []
    list.append(val)
    return list

使用这个改进的实现,输出将是:

list1 = [10]
list2 = [123]
list3 = ['a']

相关学习推荐:python视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer