TypeError: มีหลายค่าสำหรับอาร์กิวเมนต์


143

ฉันอ่านกระทู้อื่น ๆ ที่เกี่ยวข้องกับข้อผิดพลาดนี้และดูเหมือนว่าปัญหาของฉันมีความแตกต่างที่น่าสนใจกว่าโพสต์ทั้งหมดที่ฉันอ่านจนถึงตอนนี้กล่าวคือโพสต์อื่น ๆ ทั้งหมดมีข้อผิดพลาดเกี่ยวกับผู้ใช้ที่สร้างขึ้น คลาสหรือทรัพยากรระบบในตัว ฉันกำลังประสบปัญหานี้เมื่อเรียกใช้ฟังก์ชันฉันคิดไม่ออกว่าจะทำเพื่ออะไร ความคิดใด ๆ ?

BOX_LENGTH = 100
turtle.speed(0)
fill = 0
for i in range(8):
    fill += 1
    if fill % 2 == 0:
        Horizontol_drawbox(BOX_LENGTH, fillBox = False)
    else:
        Horizontol_drawbox(BOX_LENGTH, fillBox = True)

    for i in range(8):
        fill += 1
        if fill % 2 == 0:
            Vertical_drawbox(BOX_LENGTH,fillBox = False)
        else:
            Vertical_drawbox(BOX_LENGTH,fillBox = True)

ข้อความผิดพลาด:

    Horizontol_drawbox(BOX_LENGTH, fillBox = True)
TypeError: Horizontol_drawbox() got multiple values for argument 'fillBox'

5
การประกาศHorizontol_drawboxฟังก์ชันคืออะไร? หากเริ่มต้นด้วยfillBoxนั่นคือข้อบกพร่อง (กำหนดครั้งเดียวด้วยอาร์กิวเมนต์ตำแหน่งและครั้งที่สองด้วยอาร์กิวเมนต์คำหลัก)
Cilyan

คำตอบ:


224

สิ่งนี้เกิดขึ้นเมื่อมีการระบุอาร์กิวเมนต์คำสำคัญที่เขียนทับอาร์กิวเมนต์ตำแหน่ง ตัวอย่างเช่นลองจินตนาการถึงฟังก์ชันที่วาดกล่องสี ฟังก์ชันจะเลือกสีที่จะใช้และมอบหมายการวาดของกล่องไปยังฟังก์ชันอื่นโดยถ่ายทอดอาร์กิวเมนต์พิเศษทั้งหมด

def color_box(color, *args, **kwargs):
    painter.select_color(color)
    painter.draw_box(*args, **kwargs)

จากนั้นโทร

color_box("blellow", color="green", height=20, width=30)

จะล้มเหลวเนื่องจากมีการกำหนดค่าสองค่าให้color: "blellow"เป็นตำแหน่งและ"green"เป็นคำหลัก ( painter.draw_boxควรจะยอมรับheightและwidthข้อโต้แย้ง)

นี่เป็นเรื่องง่ายที่จะเห็นในตัวอย่าง แต่แน่นอนว่าหากมีการผสมผสานระหว่างอาร์กิวเมนต์ในการโทรการดีบักอาจไม่ใช่เรื่องง่าย:

# misplaced height and width
color_box(20, 30, color="green")

ที่นี่colorได้รับมอบหมาย20แล้วargs=[30]และได้รับมอบหมายอีกครั้งcolor"green"


น่าสนใจ - เมื่อฉันพบข้อผิดพลาดนี้มันก็เกี่ยวกับการcolorโต้แย้ง ปัญหาแตกต่างกันเล็กน้อย - model_matrixอาร์กิวเมนต์ของฉันกลายเป็นคำหลักเท่านั้นและรหัสเดิมบางรหัสได้ส่งผ่านไปเป็นอาร์กิวเมนต์ตำแหน่ง คาดว่าจะมี API ใหม่colorและมีเมทริกซ์ 4x4 แทน
Tomasz Gandor

สวัสดีฉันไม่เข้าใจสำหรับตัวอย่างที่สอง When a keyword argument is specified that overwrites a positional argumentนอกจากนี้ยังตอบสนองเงื่อนไข: แต่ทำไมหลังถึงได้ผล? อะไรคือกฎเมื่อ python กำหนดอาร์กิวเมนต์ ขอบคุณ.
Alston

2
@Stallman: ตัวอย่างที่สองที่ฉันให้ก็เป็นตัวอย่างที่ไม่ได้ผลเช่นกัน color = 20 ขัดแย้งกับ color = "green" กฎสำหรับการมอบหมายจะได้รับทันที ข้อมูลเพิ่มเติม: docs.python.org/3/tutorial/controlflow.html#keyword-argumentsโดยเฉพาะตัวอย่าง "การโทรที่ไม่ถูกต้อง" ที่ 3 จาก 4 ตัวอย่าง
Cilyan

71

ฉันมีปัญหาเดียวกันกับที่ทำง่ายมาก แต่ต้องใช้เวลาสักพักในการพิจารณา

ฉันได้คัดลอกคำประกาศไปที่ที่ฉันใช้มันและได้ทิ้งข้อโต้แย้งเรื่อง 'ตัวเอง' ไว้ที่นั่น แต่ฉันต้องใช้เวลานานกว่าจะตระหนักได้

ฉันมี

self.myFunction(self, a, b, c='123')

แต่มันควรจะเป็น

self.myFunction(a, b, c='123')

1
หรือแทนที่selfด้วยชื่อคลาสก่อน ;)
Tomasz Gandor

49

นอกจากนี้ยังเกิดขึ้นหากคุณลืมselfการประกาศภายในเมธอดคลาส

ตัวอย่าง:

class Example():
    def is_overlapping(x1, x2, y1, y2):
        # Thanks to https://stackoverflow.com/a/12888920/940592
        return max(x1, y1) <= min(x2, y2)

ไม่สามารถเรียกมันได้เช่นself.is_overlapping(x1=2, x2=4, y1=3, y2=5) :

{TypeError} is_overlapping () มีค่าหลายค่าสำหรับอาร์กิวเมนต์ 'x1'

งาน :

class Example():
    def is_overlapping(self, x1, x2, y1, y2):
        # Thanks to https://stackoverflow.com/a/12888920/940592
        return max(x1, y1) <= min(x2, y2)

ความคิดเห็นนี้ช่วยให้ฉันเห็นปัญหาของฉัน: ฉันลืมเพิ่มselfอาร์กิวเมนต์ในการประกาศฟังก์ชัน คือสิ่งที่ควรจะเขียนเป็นdef myFunction(self, a, b, c='123') def myFunction(a, b, c='123')และเนื่องจากbรับรายการและcใช้สเกลาร์เมื่อขาดตัวเองอาร์กิวเมนต์ก็สับสนและในที่สุดอินพุตของbจะไปcทำให้เกิดข้อผิดพลาด "หลายอาร์กิวเมนต์" ฉันทำผิดพลาดเพราะฉันทดสอบวิธีการภายในนี้นอกชั้นเรียนและลืมใส่selfกลับเข้าไปหวังว่าจะเป็นประโยชน์สำหรับคนอื่น!
yuqli

@yuqli นี่คือสิ่งที่ฉันประสบปัญหานี้เช่นกัน ;) ยินดีที่ได้ทราบว่าโพสต์นี้ช่วยคุณได้
gies0r

1
ช่วยฉันได้พอสมควรเช่นกัน :)
nexla

ยังใช้งานได้หลังจากตกแต่งฟังก์ชันด้วย@staticmethodซึ่งอาจเป็นแนวทางที่ดีกว่าเมื่อselfไม่จำเป็นต้องใช้โดยเนื้อแท้
ayorgo

22

ปัญหาของฉันคล้ายกับ Q --- ten แต่ในกรณีของฉันคือฉันลืมที่จะระบุอาร์กิวเมนต์ตนเองให้กับฟังก์ชันคลาส:

class A:
    def fn(a, b, c=True):
        pass

ควรจะกลายเป็น

class A:
    def fn(self, a, b, c=True):
        pass

การใช้งานที่ผิดพลาดนี้ยากที่จะเห็นเมื่อเรียกเมธอดคลาสเป็น:

a_obj = A()
a.fn(a_val, b_val, c=False)

ซึ่งจะได้ผลกTypeError: got multiple values for argument. หวังว่าคำตอบที่เหลือจะชัดเจนเพียงพอสำหรับทุกคนที่จะเข้าใจและแก้ไขข้อผิดพลาดได้อย่างรวดเร็ว ถ้าไม่หวังว่าคำตอบนี้จะช่วยคุณได้!


2
โอ้มนุษย์การลืม "ตัวเอง" ก็เป็นปัญหาของฉันเช่นกันสิ่งที่เป็นข้อยกเว้นที่ทำให้เข้าใจผิดถูกโยนทิ้ง
pcko1

3

พูดง่ายๆว่าคุณไม่สามารถทำสิ่งต่อไปนี้:

class C(object):
    def x(self, y, **kwargs):
        # Which y to use, kwargs or declaration? 
        pass

c = C()
y = "Arbitrary value"
kwargs["y"] = "Arbitrary value"
c.x(y, **kwargs) # FAILS

เนื่องจากคุณส่งตัวแปร 'y' เข้าไปในฟังก์ชันสองครั้ง: หนึ่งครั้งเป็น kwargs และอีกครั้งเป็นการประกาศฟังก์ชัน


2

ฉันถูกพามาที่นี่ด้วยเหตุผลที่ยังไม่ได้กล่าวถึงอย่างชัดเจนในคำตอบจนถึงตอนนี้ดังนั้นเพื่อช่วยผู้อื่นให้พ้นปัญหา:

ข้อผิดพลาดนี้ยังเกิดขึ้นหากอาร์กิวเมนต์ของฟังก์ชันมีการเปลี่ยนแปลงลำดับ - ด้วยเหตุผลเดียวกับในคำตอบที่ยอมรับ: อาร์กิวเมนต์ตำแหน่งปะทะกับอาร์กิวเมนต์คำสำคัญ

ในกรณีของฉันเป็นเพราะลำดับอาร์กิวเมนต์ของset_axisฟังก์ชันPandas เปลี่ยนไประหว่าง 0.20 ถึง 0.22:

0.20: DataFrame.set_axis(axis, labels)
0.22: DataFrame.set_axis(labels, axis=0, inplace=None)

การใช้ตัวอย่างที่พบโดยทั่วไปสำหรับ set_axis ทำให้เกิดข้อผิดพลาดที่สับสนนี้เนื่องจากเมื่อคุณโทร:

df.set_axis(['a', 'b', 'c'], axis=1)

ก่อนหน้า 0.22 ['a', 'b', 'c']ถูกกำหนดให้กับแกนเนื่องจากเป็นอาร์กิวเมนต์แรกจากนั้นอาร์กิวเมนต์ตำแหน่งจะให้ "หลายค่า"

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.