TypeError: मेथड () में 1 स्थितियुक्त तर्क है लेकिन 2 दिए गए थे


269

अगर मेरे पास एक वर्ग है ...

class MyClass:

    def method(arg):
        print(arg)

... जो मैं एक वस्तु बनाने के लिए उपयोग ...

my_object = MyClass()

... जिस पर मैं ऐसे बुलाता हूं method("foo")...

>>> my_object.method("foo")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: method() takes exactly 1 positional argument (2 given)

... पायथन मुझे क्यों बताता है कि मैंने इसे दो तर्क दिए, जब मैंने केवल एक दिया था?


उस संदेश में umpteen कारण हैं; यहाँ विशिष्ट कारण यह है कि सभी उदाहरण विधियाँ पहले arg की अपेक्षा करती हैं, जिसे हम कस्टम कहते हैं self। इसलिए घोषित def method(arg):करना एक विधि के लिए गलत है, यह होना चाहिए def method(self, arg):। जब विधि प्रेषण इसके खिलाफ method(arg):दो मापदंडों को कॉल और मैच करने की कोशिश करता है self, arg, तो आपको वह त्रुटि मिलती है।
एसएमसीआई

जवाबों:


367

पायथन में, यह:

my_object.method("foo")

... वाक्यगत शर्करा है , जो दुभाषिया पर्दे के पीछे अनुवाद करता है:

MyClass.method(my_object, "foo")

... जो, जैसा कि आप देख सकते हैं, वास्तव में दो तर्क हैं - यह सिर्फ इतना है कि पहले वाला अंतर्निहित है, कॉल करने वाले के दृष्टिकोण से।

ऐसा इसलिए है क्योंकि अधिकांश विधियाँ उस वस्तु के साथ कुछ काम करती हैं, जिस पर उन्हें बुलाया जाता है, इसलिए उस वस्तु को विधि के अंदर भेजे जाने के लिए कुछ तरीके की आवश्यकता होती है। सम्मेलन द्वारा, इस पहले तर्क को selfविधि परिभाषा के अंदर कहा जाता है:

class MyNewClass:

    def method(self, arg):
        print(self)
        print(arg)

यदि आप method("foo")किसी उदाहरण पर कॉल करते हैं MyNewClass, तो यह अपेक्षित है:

>>> my_new_object = MyNewClass()
>>> my_new_object.method("foo")
<__main__.MyNewClass object at 0x29045d0>
foo

कभी-कभी (लेकिन अक्सर नहीं), आप वास्तव में उस वस्तु के बारे में परवाह नहीं करते हैं जो आपकी विधि से बाध्य है, और उस परिस्थिति में, आप ऐसा कहने के लिए बिल्टइन फ़ंक्शन के साथ विधि को सजा सकते staticmethod()हैं:

class MyOtherClass:

    @staticmethod
    def method(arg):
        print(arg)

... किस मामले में आपको selfविधि परिभाषा में एक तर्क जोड़ने की आवश्यकता नहीं है , और यह अभी भी काम करता है:

>>> my_other_object = MyOtherClass()
>>> my_other_object.method("foo")
foo

99
संक्षेप में: selfविधि में पहले तर्क के रूप में जोड़ने से समस्या हल हो जाती है।
amoebe

@amoebe - मेरे व्यक्ति का प्रकार
कार्लोस

21

इस प्रकार की त्रुटि का सामना करने पर विचार करने के लिए कुछ और:

मैं इस त्रुटि संदेश में चल रहा था और इस पोस्ट को उपयोगी पाया। मेरे मामले में यह पता चला है कि __init__()जहां वस्तु वस्‍तु विरासत में मिली थी, मैंने उसे ओवरराइड कर दिया था।

विरासत में मिला उदाहरण लंबा है, इसलिए मैं एक और सरल उदाहरण को छोड़ दूंगा जो विरासत का उपयोग नहीं करता है:

class MyBadInitClass:
    def ___init__(self, name):
        self.name = name

    def name_foo(self, arg):
        print(self)
        print(arg)
        print("My name is", self.name)


class MyNewClass:
    def new_foo(self, arg):
        print(self)
        print(arg)


my_new_object = MyNewClass()
my_new_object.new_foo("NewFoo")
my_bad_init_object = MyBadInitClass(name="Test Name")
my_bad_init_object.name_foo("name foo")

परिणाम है:

<__main__.MyNewClass object at 0x033C48D0>
NewFoo
Traceback (most recent call last):
  File "C:/Users/Orange/PycharmProjects/Chapter9/bad_init_example.py", line 41, in <module>
    my_bad_init_object = MyBadInitClass(name="Test Name")
TypeError: object() takes no parameters

PyCharm ने इस टाइपो को नहीं पकड़ा। न ही नोटपैड ++ (अन्य संपादकों / आईडीई की ताकत)।

दी, यह एक "कोई पैरामीटर नहीं लेता है" टाइपएयर है, यह पायथन में ऑब्जेक्ट इनिशियलाइज़ेशन के संदर्भ में, एक की उम्मीद करते समय "मिला दो" से बहुत अलग नहीं है।

विषय को संबोधित करते हुए: सिंटैक्टली सही होने पर एक ओवरलोडिंग इनिशियलाइज़र का उपयोग किया जाएगा, लेकिन यदि इसे अनदेखा नहीं किया जाएगा और इसके बजाय अंतर्निहित उपयोग किया जाएगा। ऑब्जेक्ट इस की अपेक्षा / संभाल नहीं करेगा और त्रुटि को फेंक दिया गया है।

साइटैक्स त्रुटि के मामले में: फिक्स सरल है, बस कस्टम इनिट स्टेटमेंट को संपादित करें:

def __init__(self, name):
    self.name = name

1
SyntaxErrorयहाँ कोई नहीं है। कोड वाक्यात्मक रूप से सही है; यह केवल सही तरीके से नाम की एक विधि को परिभाषित करता है ___init__, जिसे कोई भी विशेष विधि के बजाय कभी भी कॉल नहीं करता है __init__। इसीलिए किसी भी त्रुटि का पता नहीं चलता - क्योंकि पता लगाने वाला कोई नहीं है।
21

14

सरल शब्दों में।

पायथन में आपको selfकक्षाओं में सभी परिभाषित तरीकों के पहले तर्क के रूप में तर्क जोड़ना चाहिए :

class MyClass:
  def method(self, arg):
    print(arg)

तब आप अपने अंतर्ज्ञान के अनुसार अपनी विधि का उपयोग कर सकते हैं:

>>> my_object = MyClass()
>>> my_object.method("foo")
foo

इससे आपकी समस्या का समाधान हो जाना चाहिए :)

एक बेहतर समझ के लिए, आप इस प्रश्न के उत्तर भी पढ़ सकते हैं: स्वयं का उद्देश्य क्या है?


2
इस उत्तर में क्या गलत है? किसी ने उसे नकारात्मक बिंदु क्यों दिया? आखिरकार, यह सवाल का जवाब है और अन्य उत्तरों की तुलना में इसकी सादगी से अलग है, जो कुछ लोगों के लिए महत्वपूर्ण हो सकता है जो उत्तर की तलाश में हैं। है ना?
सिमहूमिलिको 21

10

पायथन के लिए नवागंतुक, मेरे पास यह मुद्दा था जब मैं अजगर की **सुविधा का गलत तरीके से उपयोग कर रहा था । इस परिभाषा को कहीं से कॉल करने की कोशिश कर रहा है:

def create_properties_frame(self, parent, **kwargs):

दोहरे स्टार के बिना कॉल का उपयोग करने से समस्या उत्पन्न हो रही थी:

self.create_properties_frame(frame, kw_gsp)

TypeError: create_properties_frame () 2 स्थितिगत तर्क लेता है, लेकिन 3 दिए गए थे

समाधान को **तर्क में जोड़ना है:

self.create_properties_frame(frame, **kw_gsp)

1
जावास्क्रिप्ट से आ रहा है, मैं एक सूची या शब्दकोश को एक तर्क के रूप में पारित करने में सक्षम होने की उम्मीद करता हूं। लेकिन ऐसा लगता है कि यह नहीं है कि पायथन कैसे काम करता है: आपको सूची को * या ** के साथ नष्ट करना होगा, बाद वाले को एक कीवर्ड तर्क सूची के लिए।
लिटिल ब्रेन

1
@LittleBrain: यदि आप चाहते हैं कि आप एक सूची (या तानाशाही) पास कर सकते हैं यदि आप चाहते हैं कि उन्हें समारोह के अंदर एक सूची (/ तानाशाही) के रूप में माना जाए। लेकिन अगर आप चाहते हैं कि उनके व्यक्तिगत मान फंक्शन में args (/ kwargs) के मुकाबले अनपैक्ड और मैच किए जाएं, तो आपको *args(/ **kwargs) सिंटैक्स की आवश्यकता है।
मुस्कान

9

यह तब होता है जब आप मापदंडों की संख्या __init__()या किसी अन्य विधि की तलाश नहीं करते हैं।

उदाहरण के लिए:

class Dog:
    def __init__(self):
        print("IN INIT METHOD")

    def __unicode__(self,):
        print("IN UNICODE METHOD")

    def __str__(self):
        print("IN STR METHOD")

obj=Dog("JIMMY",1,2,3,"WOOF")

जब आप उपरोक्त कार्यक्रम चलाते हैं, तो यह आपको एक त्रुटि देता है:

TypeError: __init __ () में 1 स्थितीय तर्क है, लेकिन 6 दिए गए थे

हम इस चीज़ से कैसे छुटकारा पा सकते हैं?

बस मापदंडों को पारित करें, किस __init__()विधि की तलाश है

class Dog:
    def __init__(self, dogname, dob_d, dob_m, dob_y, dogSpeakText):
        self.name_of_dog = dogname
        self.date_of_birth = dob_d
        self.month_of_birth = dob_m
        self.year_of_birth = dob_y
        self.sound_it_make = dogSpeakText

    def __unicode__(self, ):
        print("IN UNICODE METHOD")

    def __str__(self):
        print("IN STR METHOD")


obj = Dog("JIMMY", 1, 2, 3, "WOOF")
print(id(obj))

1

आपको वास्तव में एक वर्ग बनाना चाहिए:

class accum:
    def __init__(self):
        self.acc = 0
    def accumulator(self, var2add, end):
        if not end:
            self.acc+=var2add
    return self.acc

0

मेरे मामले में, मैं जोड़ना भूल गया ()

मैं इस तरह से विधि को बुला रहा था

obj = className.myMethod

लेकिन ऐसा होना चाहिए

obj = className.myMethod()

-1

इस समस्या को हल करने के लिए clsपैरामीटर पास @classmethodकरें।

@classmethod
def test(cls):
    return ''
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.