अनबाउंड विधि f () को पहले तर्क के रूप में fibo_ उदाहरण के साथ कहा जाना चाहिए (इसके बजाय क्लासोबेज उदाहरण मिला)


139

पायथन में, मैं एक कक्षा में एक विधि चलाने की कोशिश कर रहा हूँ और मुझे एक त्रुटि मिली है:

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)

स्क्रिप्ट मेनडोम

import swineflu

f = swineflu
fibo = f.fibo

fibo.f()            #TypeError is thrown here

इस त्रुटि का मतलब क्या है? इस त्रुटि के कारण क्या है?


1
क्या आप किसी वस्तु को पलटना चाहते हैं या नहीं?
थॉमस

2
वर्ग नाम को पूंजीकृत किया जाना चाहिए।
CDT

1
fibo = f.fibo()वर्ग को कोष्ठक के साथ जोड़ने की जरूरत है।
कोटलिनबॉय

आप उपयोग कर सकते हैंfibo().f()
बेनामिन जाफरी

जवाबों:


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`. 

यहां पायथन में कक्षाओं के साथ शुरुआत करने के लिए एक अच्छा ट्यूटोरियल है।


2

पायथन 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

अजगर 2 और 3 संस्करण में अंतर:

यदि आपके पास पहले से ही एक ही नाम के साथ एक वर्ग में एक डिफ़ॉल्ट विधि है और आप एक ही नाम के रूप में फिर से घोषित करते हैं तो यह उस वर्ग उदाहरण के अनबाउंड-विधि कॉल के रूप में प्रकट होगा जब आप इसे तुरंत करना चाहते थे।

यदि आप कक्षा के तरीकों को चाहते थे, लेकिन आपने उन्हें उदाहरण के तरीकों के रूप में घोषित किया।

एक आवृत्ति विधि एक ऐसी विधि है जिसका उपयोग कक्षा की आवृत्ति बनाने के लिए किया जाता है।

एक उदाहरण होगा

   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"

अजगर 2 और 3 संस्करण में अजगर 3 में लिखने के लिए वर्ग @classmethod भिन्न होता है यह स्वचालित रूप से मिलता है कि वर्ग-लेबल विधि के रूप में और @classmethod लिखने की आवश्यकता नहीं है मुझे लगता है कि यह आपकी मदद कर सकता है।


0

इसे इस्तेमाल करे। अजगर 2.7.12 के लिए हमें कंस्ट्रक्टर को परिभाषित करने की आवश्यकता है या ऑब्जेक्ट नामक एक वर्ग के उदाहरण को परिभाषित करने के बाद प्रत्येक तरीकों में स्वयं को जोड़ने की आवश्यकता है।

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)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.