bağlı olmayan yöntem f () ilk argüman olarak fibo_ örneği ile çağrılmalıdır (bunun yerine classobj örneği var)


139

Python, bir sınıfta bir yöntem çalıştırmak çalışıyorum ve bir hata alıyorum:

Traceback (most recent call last):
  File "C:\Users\domenico\Desktop\py\main.py", line 8, in <module>
    fibo.f()
  TypeError: unbound method f() must be called with fibo instance 
  as first argument (got nothing instead)

Kodu: (swineflu.py)

class fibo:
    a=0
    b=0

    def f(self,a=0):
        print fibo.b+a
        b=a;
        return self(a+1)

Komut dosyası main.py

import swineflu

f = swineflu
fibo = f.fibo

fibo.f()            #TypeError is thrown here

Bu hata ne anlama geliyor? Bu hataya ne sebep oluyor?


1
Bir nesneyi somutlaştırmak ister misiniz?
Thomas

2
Sınıf adı büyük harfle yazılmalıdır.
CDT

1
fibo = f.fibo()Sınıfı köşeli parantez ile başlatmanız gerekir.
Kotlinboy

fibo().f()
Şunu

Yanıtlar:


179

Tamam, her şeyden önce, modüle farklı bir isim vermek zorunda değilsiniz; zaten bir referansınız var (ve import) ve sadece kullanabilirsiniz. Farklı bir ad istiyorsanız sadece kullanın import swineflu as f.

İkinci olarak, sınıfı somutlaştırmak yerine sınıfa referans alıyorsunuz.

Yani bu şöyle olmalı:

import swineflu

fibo = swineflu.fibo()  # get an instance of the class
fibo.f()                # call the method f of the instance

Bir bağımlı yöntem , bir nesnenin bir örneğine bağlı olan bir tanesidir. Bir ilişkisiz bir yöntem , tabii ki, bir bileşiktir olmayan bir örneği ekli. Hata genellikle yöntemi bir örnek yerine sınıfta çağırdığınız anlamına gelir; bu, sınıfı somutlaştırmamış olduğunuz için tam olarak bu durumda olan şeydir.


1
Bunu swineflu.fibo().f()yalnızca bir kez çağırıyorsanız da yapabilirsiniz .
Kit

81

Bu hatayı mümkün olduğunca az satırla yeniden oluşturma:

>>> class C:
...   def f(self):
...     print "hi"
...
>>> C.f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method f() must be called with C instance as 
first argument (got nothing instead)

TypeError nedeniyle başarısız olur, çünkü önce sınıfı somutlaştırmadınız, iki seçeneğiniz var: 1: ya yöntemi statik bir şekilde çalıştırabilmek için statik yapın ya da 2: sınıfınızı somutlayın, böylece kapmak için bir örneğiniz olsun üzerine, yöntemi çalıştırmak için.

Yöntemi statik bir şekilde çalıştırmak istediğiniz gibi görünüyor, bunu yapın:

>>> class C:
...   @staticmethod
...   def f():
...     print "hi"
...
>>> C.f()
hi

Ya da, muhtemelen kastettiğin örnek örneği şöyle kullanmaktır:

>>> class C:
...   def f(self):
...     print "hi"
...
>>> c1 = C()
>>> c1.f()
hi
>>> C().f()
hi

Bu sizi karıştırırsa şu soruları sorun:

  1. Statik bir yöntemin davranışı ile normal bir yöntemin davranışı arasındaki fark nedir?
  2. Bir sınıfı başlatmak ne demektir?
  3. Statik yöntemlerin nasıl çalıştığı ile normal yöntemlerin arasındaki farklar.
  4. Sınıf ve nesne arasındaki farklar.

Sınıfımı başlattım ama sadece @staticmethod kullandığımda işe yarıyor. Bu açıklanabilir mi?
abeltre1

9

fibo = f.fibosınıfın kendisine atıfta bulunur. Muhtemelen fibo = f.fibo()(parantezleri not edin) sınıfın bir örneğini yapmak istediniz , bundan sonra fibo.f()doğru şekilde başarılı olmalıdır.

f.fibo.f()başarısız, çünkü aslında f(self, a=0)tedarik etmeden çağırıyorsunuz self; selfsınıfın bir örneğine sahip olduğunuzda otomatik olarak "bağlı" olur.


4

fbir (örnek) yöntemidir. Ancak, sınıf nesnesi fibo.fnerede fibo, onu çağırıyorsunuz . Bu nedenle, fbağlanmamıştır (herhangi bir sınıf örneğine bağlı değildir).

Eğer yaptıysan

a = fibo()
a.f()

bu fdurumda (örneğe bağlı a).


2
import swineflu

x = swineflu.fibo()   # create an object `x` of class `fibo`, an instance of the class
x.f()                 # call the method `f()`, bound to `x`. 

İşte Python'daki derslere başlamak için iyi bir öğretici.


2

Python 2'de (3 farklı sözdizimine sahiptir):

Ana sınıfınızı yöntemlerinden birini çağırmadan önce başlatamıyorsanız ne olur?

super(ChildClass, self).method()Üst yöntemlere erişmek için kullanın .

class ParentClass(object):
    def method_to_call(self, arg_1):
        print arg_1

class ChildClass(ParentClass):
    def do_thing(self):
        super(ChildClass, self).method_to_call('my arg')

0

Python 2 ve 3 sürümündeki farklılıklar:

Aynı ada sahip bir sınıfta zaten varsayılan bir yönteminiz varsa ve aynı ad olarak yeniden beyan ederseniz, örneği oluşturmak istediğinizde bu sınıf örneğinin ilişkisiz yöntem çağrısı olarak görünür.

Sınıf yöntemleri istiyorsanız, ancak bunları örnek yöntemleri olarak bildirdiyseniz.

Örnek yöntemi, sınıfın bir örneğini oluştururken kullanılan bir yöntemdir.

Bir örnek

   def user_group(self):   #This is an instance method
        return "instance method returning group"

Sınıf etiketi yöntemi:

   @classmethod
   def user_group(groups):   #This is an class-label method
        return "class method returning group"

Python 2 ve 3 sürümü python 3 yazmak için class @classmethod farklı otomatik olarak bir sınıf etiketi yöntemi olarak almak ve @classmethod yazmak gerekmez Ben bu size yardımcı olabilir düşünüyorum.


0

Bunu dene. Python 2.7.12 için yapıcı tanımlamamız veya her yönteme kendini eklememiz ve bunu nesne adı verilen bir sınıf örneği tanımlamamız gerekir.

import cv2

class calculator:

#   def __init__(self):

def multiply(self, a, b):
    x= a*b
    print(x)

def subtract(self, a,b):
    x = a-b
    print(x)

def add(self, a,b):
    x = a+b
    print(x)

def div(self, a,b):
    x = a/b
    print(x)

 calc = calculator()
 calc.multiply(2,3)
 calc.add(2,3)
 calc.div(10,5)
 calc.subtract(2,3)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.