metode tidak terikat f () harus dipanggil dengan instance fibo_ sebagai argumen pertama (sebagai contoh, dapatkan instance classobj)


139

Dalam Python, saya mencoba menjalankan metode di kelas dan saya mendapatkan kesalahan:

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)

Kode: (swineflu.py)

class fibo:
    a=0
    b=0

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

Script main.py

import swineflu

f = swineflu
fibo = f.fibo

fibo.f()            #TypeError is thrown here

Apa artinya kesalahan ini? Apa yang menyebabkan kesalahan ini?


1
Apakah Anda ingin membuat instance objek atau tidak?
Thomas

2
Nama kelas harus ditulis dengan huruf besar.
CDT

1
fibo = f.fibo()Perlu instanciate kelas dengan tanda kurung.
Kotlinboy

Anda dapat menggunakanfibo().f()
Benyamin Jafari

Jawaban:


179

OKE, pertama-tama, Anda tidak harus mendapatkan referensi ke modul ke nama yang berbeda; Anda sudah memiliki referensi (dari import) dan Anda bisa menggunakannya. Jika Anda ingin nama yang berbeda, gunakan saja import swineflu as f.

Kedua, Anda mendapatkan referensi ke kelas daripada membuat instance kelas.

Jadi ini seharusnya:

import swineflu

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

Sebuah metode terikat adalah salah satu yang melekat ke sebuah contoh dari sebuah objek. Sebuah metode terikat , tentu saja, salah satu yang tidak melekat ke sebuah contoh. Kesalahan biasanya berarti Anda memanggil metode pada kelas daripada pada contoh, yang persis apa yang terjadi dalam kasus ini karena Anda belum membuat instance kelas.


1
Anda juga dapat melakukannya swineflu.fibo().f()jika Anda hanya memanggilnya sekali.
Kit

81

Cara mereproduksi kesalahan ini dengan sesedikit mungkin baris:

>>> 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)

Gagal karena TypeError karena Anda tidak instantiate kelas pertama, Anda memiliki dua pilihan: 1: membuat metode statis sehingga Anda dapat menjalankannya dengan cara statis, atau 2: instantiate kelas Anda sehingga Anda memiliki instance untuk mengambil ke, untuk menjalankan metode.

Sepertinya Anda ingin menjalankan metode dengan cara statis, lakukan ini:

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

Atau, yang mungkin Anda maksudkan adalah menggunakan instantiated instance seperti ini:

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

Jika ini membingungkan Anda, ajukan pertanyaan-pertanyaan ini:

  1. Apa perbedaan antara perilaku metode statis vs perilaku metode normal?
  2. Apa yang dimaksud dengan instantiate kelas?
  3. Perbedaan antara cara metode statis dijalankan dengan metode normal.
  4. Perbedaan antara kelas dan objek.

Saya telah instantiated kelas saya tetapi hanya berfungsi ketika saya menggunakan @staticmethod. Bisakah itu dijelaskan?
abeltre1

9

fibo = f.fiboreferensi kelas itu sendiri. Anda mungkin ingin fibo = f.fibo()(perhatikan tanda kurung) untuk membuat instance kelas, setelah itu fibo.f()harus berhasil dengan benar.

f.fibo.f()gagal karena Anda pada dasarnya menelepon f(self, a=0)tanpa menyediakan self; self"terikat" secara otomatis ketika Anda memiliki instance kelas.


4

fadalah metode (contoh). Namun, Anda memanggilnya via fibo.f, di mana fiboobjek kelas. Karenanya, ftidak terikat (tidak terikat pada turunan kelas apa pun).

Jika Anda melakukannya

a = fibo()
a.f()

maka itu fterikat (ke instance 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`. 

Berikut ini adalah tutorial yang bagus untuk memulai dengan kelas dalam Python.


2

Dalam Python 2 (3 memiliki sintaks yang berbeda):

Bagaimana jika Anda tidak dapat membuat instance kelas Induk Anda sebelum Anda perlu memanggil salah satu metodenya?

Gunakan super(ChildClass, self).method()untuk mengakses metode induk.

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

Perbedaan dalam versi In python 2 dan 3:

Jika Anda sudah memiliki metode default di kelas dengan nama yang sama dan Anda menyatakan kembali sebagai nama yang sama itu akan muncul sebagai panggilan metode-tidak terikat dari instance kelas itu ketika Anda ingin instantiated.

Jika Anda menginginkan metode kelas, tetapi Anda mendeklarasikannya sebagai metode instan.

Metode instance adalah metode yang digunakan saat untuk membuat instance dari kelas.

Contohnya adalah

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

Metode label kelas:

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

Dalam versi python 2 dan 3 berbeda kelas @classmethod untuk menulis dalam python 3 secara otomatis mendapatkan itu sebagai metode kelas-label dan tidak perlu menulis @classmethod Saya pikir ini mungkin membantu Anda.


0

Coba ini. Untuk python 2.7.12 kita perlu mendefinisikan konstruktor atau perlu menambahkan diri ke setiap metode diikuti dengan mendefinisikan sebuah instance dari objek yang disebut kelas.

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)
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.