เมธอด unbound f () ต้องถูกเรียกด้วย fibo_ เช่นเป็นอาร์กิวเมนต์แรก (มีอินสแตนซ์ classobj แทน)


139

ใน 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

ข้อผิดพลาดนี้หมายความว่าอย่างไร อะไรเป็นสาเหตุของข้อผิดพลาดนี้?


1
คุณต้องการยกตัวอย่างวัตถุหรือไม่?
โทมัส

2
ชื่อคลาสควรเป็นตัวพิมพ์ใหญ่
CDT

1
fibo = f.fibo()จำเป็นต้องสร้างชั้นเรียนด้วยวงเล็บ
Kotlinboy

คุณสามารถใช้fibo().f()
Benyamin Jafari

คำตอบ:


179

ตกลงก่อนอื่นคุณไม่ต้องรับการอ้างอิงถึงโมดูลเป็นชื่ออื่น คุณมีข้อมูลอ้างอิง (จาก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

วิธีการที่ถูกผูกไว้เป็นหนึ่งที่อยู่ติดกับอินสแตนซ์ของวัตถุ วิธีผูกไว้เป็นของหลักสูตรหนึ่งที่ไม่ได้แนบมากับอินสแตนซ์ ข้อผิดพลาดมักจะหมายความว่าคุณกำลังเรียกวิธีการในชั้นเรียนมากกว่าในกรณีซึ่งเป็นสิ่งที่เกิดขึ้นในกรณีนี้เพราะคุณไม่ได้ยกระดับชั้น


1
คุณสามารถทำได้swineflu.fibo().f()ถ้าคุณโทรครั้งเดียวเท่านั้น
ชุด

81

วิธีสร้างข้อผิดพลาดนี้โดยมีบรรทัดให้น้อยที่สุด:

>>> 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 เพราะคุณไม่ได้ยกตัวอย่างคลาสก่อนคุณมีสองตัวเลือก: 1: ทำเมธอดสแตติกเพื่อให้คุณสามารถรันในแบบสแตติกหรือ 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. ความแตกต่างระหว่างคลาสและวัตถุ

ฉันสร้างอินสแตนซ์ของชั้นเรียน แต่ก็ใช้ได้เฉพาะเมื่อฉันใช้ @ staticmethod สามารถอธิบายได้ไหม?
abeltre1

9

fibo = f.fiboอ้างอิงคลาสเอง คุณอาจต้องการfibo = f.fibo()(จดวงเล็บ) เพื่อสร้างอินสแตนซ์ของคลาสหลังจากนั้นfibo.f()ควรประสบความสำเร็จอย่างถูกต้อง

f.fibo.f()ล้มเหลวเพราะคุณเป็นหลักเรียกf(self, a=0)โดยไม่ต้องจัดหาself; selfถูก "ผูก" โดยอัตโนมัติเมื่อคุณมีอินสแตนซ์ของคลาส


4

fเป็นวิธีการ (ตัวอย่าง) อย่างไรก็ตามคุณกำลังเรียกมันผ่านfibo.fซึ่งfiboเป็นวัตถุคลาส ดังนั้นจึงfไม่ได้ผูกไว้ (ไม่ผูกพันกับอินสแตนซ์ของชั้นเรียนใด ๆ )

ถ้าคุณทำ

a = fibo()
a.f()

จากนั้นfถูกผูกไว้ (กับอินสแตนซ์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`. 

นี่คือแบบฝึกหัดที่ดีในการเริ่มต้นเรียนกับ Python


2

ใน Python 2 (3 มีไวยากรณ์ที่แตกต่าง):

ถ้าคุณไม่สามารถยกตัวอย่างคลาสพ่อแม่ของคุณก่อนที่คุณจะต้องเรียกวิธีใดวิธีหนึ่ง

ใช้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')

0

ความแตกต่างใน In python 2 และ 3 version:

หากคุณมีวิธีการเริ่มต้นในชั้นเรียนที่มีชื่อเดียวกันและคุณประกาศอีกครั้งเป็นชื่อเดียวกันมันจะปรากฏเป็นการเรียกวิธีการที่ไม่ถูกผูกไว้ของอินสแตนซ์ของชั้นเรียนนั้นเมื่อคุณต้องการสร้างอินสแตนซ์

หากคุณต้องการวิธีการเรียน แต่คุณประกาศว่าเป็นวิธีการแทน

วิธีการอินสแตนซ์เป็นวิธีการที่ใช้เมื่อสร้างอินสแตนซ์ของคลาส

ตัวอย่างจะเป็น

   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 เวอร์ชัน class @classmethod แตกต่างกันในการเขียนใน python 3 โดยอัตโนมัติจะได้รับเป็นเมธอด class-label และไม่จำเป็นต้องเขียน @classmethod ฉันคิดว่านี่อาจช่วยคุณได้


0

ลองสิ่งนี้ สำหรับ python 2.7.12 เราจำเป็นต้องกำหนด constructor หรือต้องการเพิ่ม self ให้กับแต่ละ method ตามด้วยการกำหนดอินสแตนซ์ของ class ที่เรียกว่า 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)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.