phương thức không liên kết f () phải được gọi với thể hiện fibo_ làm đối số đầu tiên (thay vào đó là thể hiện classobj)


139

Trong Python, tôi đang cố chạy một phương thức trong một lớp và tôi gặp lỗi:

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)

Mã: (swineflu.py)

class fibo:
    a=0
    b=0

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

Tập lệnh chính

import swineflu

f = swineflu
fibo = f.fibo

fibo.f()            #TypeError is thrown here

Lỗi này nghĩa là gì? Điều gì gây ra lỗi này?


1
Bạn có muốn khởi tạo một đối tượng hay không?
Thomas

2
Tên lớp nên được viết hoa.
CDT

1
fibo = f.fibo()Cần phát sinh lớp học với dấu ngoặc.
Kotlinboy

Bạn có thể sử dụngfibo().f()
Benyamin Jafari

Câu trả lời:


179

OK, trước hết, bạn không cần phải tham chiếu đến mô-đun thành một tên khác; bạn đã có một tài liệu tham khảo (từ import) và bạn chỉ có thể sử dụng nó. Nếu bạn muốn một tên khác chỉ cần sử dụng import swineflu as f.

Thứ hai, bạn đang nhận được một tài liệu tham khảo cho lớp thay vì khởi tạo lớp.

Vì vậy, điều này nên là:

import swineflu

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

Một phương thức ràng buộc là một phương thức được gắn vào một thể hiện của một đối tượng. Một phương pháp cởi ra là, tất nhiên, một trong đó là không gắn liền với một ví dụ. Lỗi thường có nghĩa là bạn đang gọi phương thức trên lớp chứ không phải trên một cá thể, đó chính xác là những gì đã xảy ra trong trường hợp này vì bạn đã không khởi tạo lớp.


1
Bạn cũng có thể làm swineflu.fibo().f()nếu bạn chỉ gọi nó một lần.
Bộ

81

Cách tái tạo lỗi này với càng ít dòng càng tốt:

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

Không thành công vì TypeError vì bạn không khởi tạo lớp trước, bạn có hai lựa chọn: 1: làm cho phương thức tĩnh để bạn có thể chạy nó theo cách tĩnh hoặc 2: khởi tạo lớp của bạn để bạn có thể lấy một ví dụ lên, để chạy phương thức.

Có vẻ như bạn muốn chạy phương thức theo cách tĩnh, hãy làm điều này:

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

Hoặc, những gì bạn có thể có nghĩa là sử dụng ví dụ khởi tạo như thế này:

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

Nếu điều này làm bạn bối rối, hãy hỏi những câu hỏi sau:

  1. Sự khác biệt giữa hành vi của một phương thức tĩnh so với hành vi của một phương thức bình thường là gì?
  2. Nó có nghĩa là gì để khởi tạo một lớp học?
  3. Sự khác nhau giữa cách các phương thức tĩnh được chạy so với các phương thức bình thường.
  4. Sự khác biệt giữa lớp và đối tượng.

Tôi đã khởi tạo lớp của mình nhưng nó chỉ hoạt động khi tôi sử dụng @staticmethod. Điều đó có thể được giải thích?
abeltre1

9

fibo = f.fibotài liệu tham khảo chính lớp. Bạn có thể muốn fibo = f.fibo()(lưu ý dấu ngoặc đơn) để tạo một thể hiện của lớp, sau đó fibo.f()sẽ thành công chính xác.

f.fibo.f()thất bại vì về cơ bản bạn đang gọi f(self, a=0)mà không cung cấp self; selfđược "ràng buộc" tự động khi bạn có một thể hiện của lớp.


4

flà một phương thức (ví dụ). Tuy nhiên, bạn đang gọi nó thông qua fibo.f, fibođối tượng lớp ở đâu. Do đó, fkhông bị ràng buộc (không bị ràng buộc với bất kỳ thể hiện lớp nào).

Nếu bạn đã làm

a = fibo()
a.f()

sau đó fbị ràng buộc (ví dụ 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`. 

Đây là một hướng dẫn tốt để bắt đầu với các lớp trong Python.


2

Trong Python 2 (3 có cú pháp khác nhau):

Điều gì xảy ra nếu bạn không thể khởi tạo lớp Parent trước khi bạn cần gọi một trong các phương thức của nó?

Sử dụng super(ChildClass, self).method()để truy cập các phương thức cha.

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

Sự khác biệt trong phiên bản python 2 và 3:

Nếu bạn đã có một phương thức mặc định trong một lớp có cùng tên và bạn khai báo lại dưới cùng một tên, nó sẽ xuất hiện dưới dạng cuộc gọi phương thức không liên kết của thể hiện của lớp đó khi bạn muốn khởi tạo nó.

Nếu bạn muốn các phương thức lớp, nhưng thay vào đó bạn đã khai báo chúng như các phương thức cá thể.

Một phương thức cá thể là một phương thức được sử dụng khi tạo một thể hiện của lớp.

Một ví dụ sẽ là

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

Phương pháp nhãn lớp:

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

Trong phiên bản python 2 và 3 khác nhau, lớp @ classmethod viết bằng python 3, nó tự động lấy đó làm phương thức nhãn lớp và không cần phải viết @ classmethod Tôi nghĩ rằng điều này có thể giúp bạn.


0

Thử cái này. Đối với python 2.7.12, chúng ta cần định nghĩa hàm tạo hoặc cần tự thêm vào mỗi phương thức theo sau bằng cách định nghĩa một thể hiện của một lớp được gọi là đối tượng.

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.