web-dev-qa-db-ja.com

アンバインドされたメソッドf()は最初の引数としてfibo_ instanceを使って呼び出さなければなりません(代わりにclassobjインスタンスを取得しました)

Pythonでは、クラス内でメソッドを実行しようとしていますが、エラーが発生します。

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)

コード:(swineflu.py)

class fibo:
    a=0
    b=0

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

スクリプトmain.py

import swineflu

f = swineflu
fibo = f.fibo

fibo.f()            #TypeError is thrown here

このエラーはどういう意味ですか?このエラーの原因は何ですか?

136
DomeWTF

まず最初に、モジュールへの参照を別の名前にする必要はありません。あなたは(importからの)参照をすでに持っていて、それを使うことができます。別の名前が必要な場合はimport swineflu as fを使用してください。

次に、クラスをインスタンス化するのではなく、クラスへの参照を取得しています。

だからこれはする必要があります:

import swineflu

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

バウンドメソッドは、オブジェクトのインスタンスにアタッチされているものです。 バインドされていないメソッドは、もちろん、インスタンスに付加されているではないです。このエラーは通常、インスタンスではなくクラスでメソッドを呼び出していることを意味します。これは、クラスをインスタンス化していないため、この場合に発生したこととまったく同じです。

172
kindall

できるだけ少ない行でこのエラーを再現する方法:

>>> 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が原因で失敗します。2つの選択肢があります。メソッドを実行します。

これはあなたが静的にメソッドを実行したいようです、これをしてください:

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

または、あなたがおそらく意図したのは、このようなインスタンス化されたインスタンスを使用することです。

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

これがあなたを混乱させる場合、これらの質問をしてください。

  1. 静的メソッドの動作と通常のメソッドの動作の違いは何ですか?
  2. クラスをインスタンス化するとはどういう意味ですか?
  3. 静的メソッドの実行方法と通常のメソッドの違い.
  4. クラスとオブジェクトの違い.
78
Eric Leschinski

fibo = f.fiboはクラス自体を参照します。 fibo = f.fibo()(括弧に注意)がクラスのインスタンスになるようにしたいと思うかもしれません。その後、fibo.f()は正しく成功するはずです。

selfを指定せずにf.fibo.f()を呼び出しているため、f(self, a=0)は失敗します。 selfは、クラスのインスタンスがあるときに自動的に「バインド」されます。

9
Mark Rushakoff

fは(インスタンス)メソッドです。しかし、あなたはそれをfibo.f経由で呼び出しています。ここでfiboはクラスオブジェクトです。したがって、fはバインドされていません(どのクラスインスタンスにもバインドされていません)。

あなたがした場合

a = fibo()
a.f()

それから、そのfが(インスタンスaに)バインドされます。

3
lijie

Python 2(3では構文が異なります)

メソッドの1つを呼び出す必要がある前にParentクラスをインスタンス化できない場合はどうなりますか?

親メソッドにアクセスするにはsuper(ChildClass, self).method()を使用してください。

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')
2
Peter Graham
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`. 

ここ はPythonでクラスを始めるための良いチュートリアルです。

2
user225312

これを試して。 python 2.7.12では、コンストラクタを定義するか、各メソッドにselfを追加してからobjectというクラスのインスタンスを定義する必要があります。

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

Python 2と3のバージョンの違い:

同じ名前のクラスにデフォルトのメソッドがすでにあり、同じ名前で再宣言した場合は、インスタンス化するときにそのクラスインスタンスのunbound-method呼び出しとして表示されます。

あなたがクラスメソッドを望んでいたが、代わりにそれらをインスタンスメソッドとして宣言した場合。

インスタンスメソッドは、クラスのインスタンスを作成するときに使用されるメソッドです。

例は

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

クラスラベル方法:

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

Python 2と3のバージョンでは、python 3で書くためのクラス@classmethodが異なります。それは自動的にクラスラベルメソッドとしてそれを取得します。

0
Projesh Bhoumik