TypeError: có nhiều giá trị cho đối số


139

Tôi đã đọc các chủ đề khác liên quan đến lỗi này và có vẻ như vấn đề của tôi có một sự khác biệt thú vị so với tất cả các bài đăng tôi đọc cho đến nay, cụ thể là, tất cả các bài đăng khác cho đến nay đều có lỗi liên quan đến người dùng được tạo lớp hoặc tài nguyên hệ thống dựng sẵn. Tôi đang gặp vấn đề này khi gọi một hàm, tôi không thể tìm ra nó có thể dùng để làm gì. Có ý kiến ​​gì không?

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)

Thông báo lỗi:

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

5
Khai báo của Horizontol_drawboxhàm là gì? Nếu nó bắt đầu bằng fillBoxthì đó là lỗi (được gán một lần với đối số vị trí và lần thứ hai với đối số từ khóa).
Cilyan

Câu trả lời:


220

Điều này xảy ra khi một đối số từ khóa được chỉ định ghi đè lên một đối số vị trí. Ví dụ, hãy tưởng tượng một chức năng vẽ một hộp màu. Hàm chọn màu sẽ được sử dụng và ủy thác bản vẽ của hộp cho hàm khác, chuyển tiếp tất cả các đối số phụ.

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

Sau đó, cuộc gọi

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

sẽ thất bại vì hai giá trị được gán cho color: "blellow"là vị trí và "green"từ khóa. ( painter.draw_boxđược cho là chấp nhận heightwidthlập luận).

Điều này dễ thấy trong ví dụ, nhưng tất nhiên nếu một kết hợp các đối số trong cuộc gọi, có thể không dễ gỡ lỗi:

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

Ở đây, colorđược chỉ định 20, sau đó args=[30]colormột lần nữa được chỉ định "green".


Thú vị - khi tôi gặp lỗi này, đó cũng là về một colorcuộc tranh cãi. Vấn đề hơi khác một chút - model_matrixđối số của tôi chỉ trở thành từ khóa và một số mã kế thừa đã được thông qua dưới dạng đối số vị trí. API mới đã được mong đợi colorvà thay vào đó có một ma trận 4 x 4.
Tomasz Gandor

Xin chào, tôi không lấy nó làm ví dụ thứ hai. Nó cũng thỏa mãn điều kiện : When a keyword argument is specified that overwrites a positional argument. Nhưng tại sao cái sau có thể làm việc? Quy tắc gì khi python gán các đối số. Cảm ơn bạn.
Alston

2
@Stallman: ví dụ thứ hai tôi đưa ra cũng là một ví dụ không hoạt động. color = 20 xung đột với color = "green". Quy tắc chuyển nhượng được đưa ra ngay sau đó. Thông tin thêm: docs.python.org/3/tutorial/controlflow.html#keyword-argument Đặc biệt là thứ 3 trong số 4 ví dụ "cuộc gọi không hợp lệ".
Cilyan

70

Tôi đã có cùng một vấn đề rất dễ thực hiện, nhưng tôi phải mất một thời gian để xem qua.

Tôi đã sao chép tờ khai vào nơi tôi đang sử dụng và để lại tranh luận về "cái tôi" ở đó, nhưng tôi phải mất nhiều thời gian để nhận ra điều đó.

Tôi đã có

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

nhưng nó nên có

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

1
Hoặc thay thế đầu tiên selfvới tên lớp. ;)
Tomasz Gandor

49

Điều này cũng xảy ra nếu bạn quên selfkhai báo bên trong các phương thức lớp.

Thí dụ:

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

Thất bại gọi nó như self.is_overlapping(x1=2, x2=4, y1=3, y2=5) với:

{TypeError} is_overlicking () có nhiều giá trị cho đối số 'x1'

CÔNG TRÌNH :

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)

Nhận xét này giúp tôi phát hiện ra vấn đề của mình: Tôi quên thêm một selfđối số bên trong khai báo hàm. tức là những gì nên được def myFunction(self, a, b, c='123')viết là def myFunction(a, b, c='123'). Và bởi vì blấy một danh sách và clấy vô hướng, khi thiếu bản thân, các đối số bị rối và cuối cùng là đầu vào bđi vào c, gây ra lỗi "nhiều đối số". Tôi mắc lỗi này vì tôi đã thử nghiệm phương thức nội bộ này bên ngoài lớp và quên thêm phần selfquay lại. Hy vọng hữu ích cho người khác!
yuqli

@yuqli Đây chính xác là cách tôi gặp vấn đề này. ;) Rất vui khi biết rằng bài đăng này đã giúp bạn.
gies0r

1
cũng tiết kiệm cho tôi khá nhiều thời gian :)
nexla

Cũng hoạt động sau khi trang trí chức năng @staticmethodmà có thể là một cách tiếp cận tốt hơn khi selfkhông cần thiết.
ayorgo

21

Vấn đề của tôi tương tự như Q --- ten, nhưng trong trường hợp của tôi, đó là tôi đã quên cung cấp đối số tự cho một hàm lớp:

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

Nên trở thành

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

Việc triển khai bị lỗi này khó thấy khi gọi phương thức lớp là:

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

Mà sẽ mang lại a TypeError: got multiple values for argument. Hy vọng, phần còn lại của câu trả lời ở đây đủ rõ ràng để bất cứ ai cũng có thể nhanh chóng hiểu và sửa lỗi. Nếu không, hy vọng câu trả lời này sẽ giúp bạn!


2
Ôi trời, quên "cái tôi" cũng là vấn đề của tôi, thật là một ngoại lệ sai lầm bị ném
pcko1

3

Đơn giản chỉ cần đặt bạn không thể làm như sau:

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

Bởi vì bạn chuyển biến 'y' vào hàm hai lần: một lần dưới dạng kwarg và một lần dưới dạng khai báo hàm.


2

Tôi đã được đưa đến đây vì một lý do không được đề cập rõ ràng trong các câu trả lời cho đến nay, vì vậy để cứu người khác những rắc rối:

Lỗi cũng xảy ra nếu các đối số chức năng đã thay đổi thứ tự - vì lý do tương tự như trong câu trả lời được chấp nhận: các đối số vị trí xung đột với các đối số từ khóa.

Trong trường hợp của tôi, đó là do thứ tự đối số của set_axishàm Pandas thay đổi trong khoảng từ 0,20 đến 0,22:

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

Sử dụng các ví dụ thường thấy cho set_axis dẫn đến lỗi khó hiểu này, kể từ khi bạn gọi:

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

trước 0,22, ['a', 'b', 'c']được gán cho trục vì đó là đối số đầu tiên và sau đó đối số vị trí cung cấp "nhiều giá trị".

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.