2009-08-09 3 views
1

У меня есть эта функция вызова здесь:Где скрытый параметр?

import test_hosts 

test_hosts.LocalTestHost(mst, port, local_ip, remote_if_mac, remote_if_ip, service_port) 

и когда я запускаю его, интерпретатор выходит из строя, и говорит, что я передаю 6 параметров в функцию, которая принимает 7 параметров.

LocalTestHost - класс, который его конструктор принимает параметр self и шесть других: в результате получается в общей сложности 7 параметров. Это его декларация:

class LocalTestHost: 

    def __init__(self, mst, port, local_ip, remote_if_mac, remote_if_ip, service_port): 
     ... 

Я устал от этого кода часами, и я не могу найти проблему. Когда я запускаю это как есть, он терпит неудачу, потому что я пропускаю 6 параметров, которых слишком мало, если я вызову конструктор с добавленным параметром, чтобы увидеть, что я все еще могу считать, он говорит, что я пропускаю 8 параметров, что тоже многие.

+3

Я пробовал вырезать и вставлять ваш пример в Python 2.5 и не могу воспроизвести его. Можете ли вы опубликовать более полный пример, который не подходит? – Nelson

+2

Сначала вы должны создать минимальный тест, который воспроизводит проблему. Это должен быть файл sinlge, а конструктор должен иметь как можно меньше аргументов. – stepancheg

+1

Несколько идей: 1) Вы уверены, что это аргументы, переданные __init__, о которых жалуется интерпретатор, а не какой-либо вызов в цепочке? 2) Вы каким-то образом/где-то сделали __init__ статическим или иным образом его модифицировали? 3) Испытывали ли вы определение __init __ (* args), а затем печатали аргументы, чтобы увидеть, какие параметры фактически переданы? – balpha

ответ

1

Боже мой, я был идиотом. Мне нужно более внимательно прочитать сообщения об ошибках.

Код, который фактически вызвал проблему, фактически отсутствовал. Это было несколько строк внутри конструктора. Вот оно:

class LocalTestHost: 

    def __init__(self, mst, port, local_ip, remote_if_mac, remote_if_ip, service_port): 
     . 
     . <some initialization code> 
     . 

     # This is the faulty line 
     self.__host_operations = HostOperationsFactory().create(
         local_ip, port, mst, remote_if_ip) 

А вот сообщение об ошибке, я все не читал, и глупо не отправлял с моим вопросом:

>>> test_hosts.LocalTestHost(1,2,3,4,5,6) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in ? 
    File "test_hosts.py", line 709, in __init__ 
    self.__host_operations = HostOperationsFactory().create(
    File "test_hosts.py", line 339, in create 
    remote_ip) 
    File "test_hosts.py", line 110, in __init__ 
    packet_size, remote_ip) 
TypeError: __init__() takes exactly 7 arguments (6 given) 

Я переработан мой код немного, и добавил параметры для нескольких методов и конструкторов, но я забыл обновить их использование в нескольких местах. Эта функция create фактически возвращает другой объект, который он создает, и его конструктор (кстати, имеет те же параметры, что и конструктор, который я выбрал) не получил все параметры, которые он должен иметь.

Я не читал сообщение полностью, и мое замешательство исходило из последней строки, в которой я передал конструктору слишком мало параметров. Теперь я также попытался добавить слишком много параметров в качестве проверки на работоспособность, и там это был конструктор, который я собирал. Я удивлен, что не видел, что в этом случае трассировка ошибок была значительно короче.

Сегодня я узнал ценный урок. Проблема в том, что я думаю, что несколько лет назад я склонял ее несколько раз.

+0

Я думаю, что всегда полезно выучить урок! Говоря об инстанцировании, возможно, ваша семантика будет более близка к '= HostOperationsFactory.create (...)'. Вам просто нужно объявить 'create()' как метод класса. И пока мы на нем, почему бы не сделать его конструктивным: '= HostOperationsFactory (...)'? –

+0

Выполнение: '= HostOperationsFactory (...)' вы подразумеваете реализацию его как функции. Звучит интересно. Интересно, какая у нас правильная практика? Функция или метод класса? –

1

Я видел эти проблемы раньше, но это было из-за того, что предыдущий код создавался таким образом, что он синтаксически исправлялся, но не так, как я предполагал.

Этот фрагмент кода не достаточно, чтобы воспроизвести проблему для меня, по крайней мере, не на 2.5.1 на OS X.

2

Еще одна идея: вы невольно вызывая старую версию кода. Убедитесь, что у вас нет файла .pyc.

+0

FWIW, я имел это случается там, где я chdir из моей директории devel и вместо того, чтобы получать версию версии модуля, я получаю более старую, которую я установил в сайтах-пакетах. – EmmEff

+0

Нет, я тоже это проверил. Я очистил рабочий каталог. Несколько раз перемещал все в другие места. Это не так. Но я тоже столкнулся с этим в своей жизни. Это может заставить вас сбить с толку. –

3

Отрывки кода, который вы вставили, выглядят отлично. Как правильно сказали другие, чтобы найти проблему, вы должны найти наименьший объем кода, который все еще имеет ошибку.

Мое предложение было бы

(1) убедитесь, что модуль test_hosts написан для версии Python, и что это на самом деле файл импортируется

(2) скопировать функцию class LocalTestHost: def __init__(... в файл и попробуйте позвонить оттуда. Это вызовет что-то вроде NameError, если вы правильно получите # params.

(3) Если вышеуказанная функция работает для вас, проверьте подпись test_hosts.LocalTestHost.__init__(), используя интроспекцию времени выполнения. кто-то может изменить его, например. __init__ = staticmethod(__init__) где-то (старый метод определения статических функций).

И, пожалуйста, сообщите нам, как это происходит!

Смежные вопросы