2015-08-24 20 views
5

Bazen, bazı değerler/dizeler işlevlerde kodlanmıştır. Örneğin, aşağıdaki işlevde, bir "sabit" karşılaştırma dizesini tanımlar ve ona karşı kontrol ederim. Bunu yapmak kötü ve dış kapsamında nasıl tanımlanması gerektiğini, bunun olduğunu bu şekilde tanımlarken perde arkasında neler olduğunu merak ediyorum neden hakkında çok fazla tartışmaya olmadanPython işlevinde sabit kodlanmış değişkenler

def foo(s): 
    c_string = "hello" 
    if s == c_string: 
     return True 
    return False 

.
Dize her çağrıyı oluşturuyor mu?
"hello" dizesi yerine [1,2,3] (veya değişebilir içeriğe sahip bir liste) aynı şey olur mu?

cevap

11

Dize değişmez olduğundan (bir tuple gibi), işlev için bytecode nesnesiyle depolanır. Çok basit ve hızlı bir dizin araması ile yüklenir. Bu, genel bir aramadan daha hızlı.

kullanarak, bytecode bir sökme de görüyoruz dis.dis() function: LOAD_CONST işlemkodu fonksiyonu için kod nesnenin bir parçası olan co_costs diziden dize nesnesini yükleyen

>>> import dis 
>>> def foo(s): 
...  c_string = "hello" 
...  if s == c_string: 
...   return True 
...  return False 
... 
>>> dis.dis(foo) 
    2   0 LOAD_CONST    1 ('hello') 
       3 STORE_FAST    1 (c_string) 

    3   6 LOAD_FAST    0 (s) 
       9 LOAD_FAST    1 (c_string) 
      12 COMPARE_OP    2 (==) 
      15 POP_JUMP_IF_FALSE  22 

    4   18 LOAD_GLOBAL    0 (True) 
      21 RETURN_VALUE   

    5  >> 22 LOAD_GLOBAL    1 (False) 
      25 RETURN_VALUE   
>>> foo.__code__.co_consts 
(None, 'hello') 

; referans yığının üstüne itilir. STORE_FAST opcode, referansı yığının en üstünden alır ve yine çok basit ve hızlı bir işlem olan yerel dizide saklar. değişken değişmezleri için

({..}, [..]) özel işlem kodları (sadece aynı yapı taşlarını izleyin daha karmaşık yapılara) hala mümkün olduğunca sabit olarak ele içeriklerle, nesneyi oluşturmak:

>>> def bar(): return ['spam', 'eggs'] 
... 
>>> dis.dis(bar) 
    1   0 LOAD_CONST    1 ('spam') 
       3 LOAD_CONST    2 ('eggs') 
       6 BUILD_LIST    2 
       9 RETURN_VALUE   

BUILD_LIST çağrı, iki sabit dize nesnesi kullanarak yeni liste nesnesini oluşturur.

İlginç bir gerçek: Bir üyelik testi için bir liste nesnesi kullandıysanız (something in ['option1', 'option2', 'option3'] Python, liste nesnesinin hiçbir zaman değiştirilmeyeceğini ve derleme zamanında sizin için bir tuple dönüştüreceğini bilir (peephole optimizasyonu olarak adlandırılır). aynı bir frozenset() nesneye dönüştürülür değişmez bir dizi için geçerlidir, ancak yalnızca Python 3.2 ve daha yeni daki örnek işlevi yerine verbosely Boolean kullanıyor Tuple or list when using 'in' in an 'if' clause?

notuna bakın; sadece kullanmış olabilir.

def foo(s): 
    c_string = "hello" 
    return s == c_string 
Aynı sonuç için

,'dan kaçınmak için Python 2'de (Python 3 True ve False anahtar kelimelerinden oluşançağrıları, değerler de sabit olarak saklanabilir).

+0

Aynı şey s == "merhaba" 'ile de aynı şey değil mi? – jonrsharpe

+0

Tuple hakkındaki yorum hakkında haklısınız, bunun yerine liste hakkında soru sormalıydım. Soruyu düzeltirim. Cevabın geri kalanı şu an için mükemmel :) –

+0

@ArthurVaiselbuh: Ben de listeleri listeledim, yanı sıra "{...}" sözlükleri ve setleri. –