2015-08-06 10 views
5

Dowiedziałem się o tym dzisiaj przez przypadek, gdy zauważyłem, że fragment kodu Pythona użył built-in functionall jako identyfikatora zmiennej do przechowywania wyniku listowania i nie spowodował błędu, więc próbowałem następujących :Dlaczego możesz przypisać wartości wbudowanym funkcjom w Pythonie?

type('abc') 
Out[1]: str 

type('abc') == str 
Out[2]: True 

str = int 

type('abc') == str 
Out[4]: False 

type('abc') 
Out[5]: str 

type = [1,2,3] 

type('abc') 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-7-a74a7df76db1> in <module>() 
----> 1 type('abc') 

TypeError: 'list' object is not callable 

Mam nadzieję, że jest to prawidłowe pytanie, gdy zapytam, dlaczego to zachowanie jest dozwolone w Pythonie.

Albo jeszcze lepiej, jak mogę się upewnić, że funkcja wbudowana jest naprawdę jak strstr i nie powiedzieć, int tak str(123) nie będą oceniane jako int(123) przez przypadek?

+3

Nie rzeczywiście przypisać dowolny wbudowany w obiekt. Zdefiniowałeś nowe globale, które maskowały wbudowane. Czemu? Ponieważ Python jest elastyczny. –

+0

Dlaczego Python powinien powstrzymać Cię od nazywania rzeczy, które chcesz? Twoim obowiązkiem jest pozostawienie samych nazw ważnych wbudowanych, jeśli chcesz, aby działały normalnie. –

+0

@MartijnPieters To całkiem interesujące, ale jak mogę się upewnić, że funkcja działa tak, jak myślę? – Vinayak

Odpowiedz

6

Python oczekuje, że weźmiesz odpowiedzialność za swój kod, dlatego. Python nie ma atrybutów prywatnych, żadnych chronionych klas i prawie żadnych ograniczeń dotyczących nazw, których można używać.

Tak, oznacza to, że możesz przypadkowo zmienić nazwę wbudowanego. Twórz wyjątki dla swojego kodu, korzystaj z wykładziny, a generalnie szybko nauczysz się wykrywać przypadkowe użycie wbudowanego, którego potrzebujesz. Nie różni się to od przypadkowego ponownego użycia jakiejkolwiek innej nazwy w kodzie.

Należy pamiętać, że po prostu maskowanie wbudowanych nazw; wyszukiwanie nazw, które nie mogą znaleźć globalnego następnego spojrzenia na wbudowaną przestrzeń nazw, więc jeśli ustawisz str na coś innego, zostanie to znalezione przed wbudowaniem. Wystarczy usunąć globalny:

>>> str = 'foobar' 
>>> isinstance('foobar', str) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: isinstance() arg 2 must be a class, type, or tuple of classes and types 
>>> del str 
>>> isinstance('foobar', str) 
True 

Alternatywą byłoby dołożyć wszelkich wbudowany nazwy zastrzeżonego słowa kluczowego, zostawiając znacznie zmniejszyło listę nazwisk, które są dozwolone, a brak elastyczności w re-definiowania tych obiektów. Python 2.7 ma na przykład 144 takie nazwy.

W tym kontekście, zobacz blog post by Guido van Rossum on why None, True and False are now keywords in Python 3:

Because you cannot use these as variable or function names anywhere, ever, in any Python program, everyone using Python has to know about all the reserved words in the language, even if they don't have any need for them. For this reason, we try to keep the list of reserved words small, and the core developers hem and haw a lot before adding a new reserved word to the language.

Powiązane problemy