2011-06-01 18 views
9

Bir saat öncesine kadar, python Foo().bar() öğesinde, örneği ilk parametre olarak geçiren Foo.bar (Foo()) için kısa bir elden başka bir şey olmadığına ikna oldum.Python yöntemi araması, static vs. örneği

class Foo (object): 
    def bar (self): print "baz" 

qux = Foo() 
qux.bar() 
Foo.bar (qux) 

Ama şimdi insanoğlunun bildiği tüm hayvanların bir listesini döndüren bir statik yöntem olarak doldurulur() olan bir sınıf Hayvan vardır: Bu örnekte son iki satır (görünüşte) aynı işi görüyor. Ayrıca, her bir Animal örneğinin, örneğinin özelliklerini rastgele değerler ile dolduran bir yöntem populate() vardır.

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 

import random 

animals = [ ("Bella", "cow"), ("Spike", "dog"), ("José", "iguana"), ("Tux", "penguin") ] 

class Animal (object): 
    @staticmethod 
    def populate (*args): return map (lambda x: Animal (*x), animals) 

    def __init__ (self, name = None, species = None): 
     def bar(): self.name, self.species = random.choice (animals) 
     self.name = name 
     self.species = species 
     self.populate = bar 

    def __repr__ (self): return "%s of species %s" % (self.name, self.species) 

print Animal.populate() 
print Animal ("Pinky", "mouse") 
qux = Animal() 
qux.populate() 
print qux 

kod çalışıyor ama ne beni şüpheli yaptı print Animal.populate (qux) statik doldurmak yöntemi denilen (ve dolayısıyla bir liste döndü ve kötü qux doldurmak vermedi) olmasıydı. Görünüşe göre, Foo().bar()'un Foo.bar (Foo()) için kısa bir elden başka bir şey olmadığı kanaatim yanlış.

Bu benim için çeşitli sorular ortaya:

  1. ben Foo().bar() nasıl hitap oluyorsa ne zaman?
  2. Foo.bar (Foo()) numaralı telefonu aradığımda ne olur?
  3. Her ikisi arasında bir iç fark var mı?
  4. Bazı temel python kavramlarını kaçırmıyorum?
  5. Statik populasyon yöntemi, bu sınıfın bir örneği üzerinden çağrılan populate yönteminden başka bir şey yapan bir sınıf yazmak zorunda kalsaydınız, bu da hangisi olur?

(Evet aynı adı olmalıdır.)

+0

Daha ilginç bir başlık, "Python yöntemi araması, statik vs. örneği" olacaktır. Bu terminolojiyi kullanarak daha fazla cevap alabilirsiniz, biraz daha teknik ve çekici. – slezica

+0

@Santiago Giriş için teşekkürler. Başlığı değiştirdim. – Hyperboreus

+2

'()' etrafındaki tüm ekstra boşluklar gözlerimi –

cevap

2

ilk adımı atlayarak edilir. Bar(), Foo.bar (fan()) ve foo.bar() (I, çünkü cevap olarak dün kaydoldu ve henüz yorum yapamazsınız) - Python (< 3.0) 'sınırlı' ve 'bağlanmamış' yöntemleri kavramından kaynaklanmaktadır - bu kesinlikle şunu gerektirir: @staticmethod veya @classmethod hariç, yöntem çağrıları Onlarla ilişkili bir örnek. Bunu açıklamak için hatırlamanız gereken bir şeyden daha kolay bir yol yoktur. Neyse ki, bu Python 3'te değişti - ayrı şeyler gitmiş gibi 'bağlı' ve 'bağlanmamış' yöntemleri kavramı ve Foo.bar() örneğin sizin için gayet iyi çalışıyor.

+0

Harika. Bu çok yardımcı oldu. – Hyperboreus

+0

Python2.7'den python3.2'ye yeni taşındım ve şimdi daha öncekinden daha az "sürpriz" yaşadım. – Hyperboreus

2

Statik yöntemler ve sınıf yöntemleri special descriptors bulunmaktadır. Tanımlayıcının __get__() yönteminin argümanları hem sınıfı hem de herhangi bir ilgili örneği içerdiğinden, argümanları metoda istedikleri şekilde girebilirler.

+0

Teşekkürler. Bağlantıyı okuyacağım ve büyük olasılıkla daha fazla soruyla geri döneceğim. – Hyperboreus

0

qnx.populate(), populate için örnekte qnx örneğine bakar. Bu yoksa, populate adı verilene kadar __mro__ izlenir.

Animals.populate(qnx) fan() arasındaki fark olarak, yukarıda arama

+0

Çok teşekkür ederim. Bunu sindirmek için biraz zamana ihtiyacım var. – Hyperboreus

+0

Python'da MRO ile izleyebilmenin bir yolu var mı? – Hyperboreus

+0

@Hyperboreus, sınıfın bir “__mro__' özniteliği var –