Подобные функции - Один работает, остальные нет - Может быть, свежий взгляд может увидеть проблему? (Python CGI) - PullRequest
1 голос
/ 22 апреля 2011

Работа над сценарием регистрации пользователя низкой интенсивности. В части скрипта проверки ошибок (которая фактически просто проверяет, чтобы убедиться, что поля не оставлены пустыми), функция "addressError" работает без каких-либо проблем.

Но если я попытаюсь создать ошибки в любом другом поле, сценарий прекратит работу. Надеюсь, кто-нибудь увидит, что мне не хватает?

Что работает:

def check_address(user, formdata):
        if formdata.has_key("streetAddress") and formdata["streetAddress"].value != "":
                streetAddress = formdata["streetAddress"].value
                return streetAddress
        else:
                addressError(user, formdata)

def addressError(user, formdata):
        feedback = {"blank_address" : "Please enter a valid street address! We won't mail you anything you don't order. Promise."}
        stepTwoError(user, formdata, "blank_address", feedback)

Что не работает:

def check_city(user, formdata):
        if formdata.has_key("city") and formdata["city"].value != "":
                city = formdata["city"].value
                return city
        else:
                cityError(user, formdata)

def cityError(user, formdata):
        feedback = {"blank_city" : "Please enter a city!"}
        stepTwoError(user, formdata, "blank_city", feedback)

def check_state(user, formdata):
        if formdata.has_key("state") and formdata["state"].value != "":
                state = formdata["state"].value
                return state
        else:
                stateError(user, formdata)

def stateError(user, formdata):
        feedback = {"blank_state" : "Please enter a state!"}
        stepTwoError(user, formdata, "blank_state", feedback)

EDIT: Код, который вызывает эти методы:

def get_stepTwoData(user, formdata):
        firstName, lastName = check_name(user, formdata)
        streetAddress = check_address(user, formdata)
        city = check_city(user, formdata)
        state = check_state(user, formdata)
        zipCode = check_zipCode(user, formdata)

        return firstName, lastName, streetAddress, city, state, zipCode

и в основном:

  if regStep == "2":
                    firstName, lastName, streetAddress, city, state, zipCode = get_stepTwoData(user, formdata)
                    make_step3(user, regStep, firstName, lastName, streetAddress, city, state, zipCode, formdata)

Насколько мне известно, эти три блока абсолютно одинаковы, причем "адрес", "штат" и "город" используются взаимозаменяемо. Фактически, я мог бы написать функцию for, чтобы охватить все три из них одновременно. Так почему же два из них не работают?

(Примечание: я не включаю функцию stepTwoError (), потому что я знаю, что она работает, поскольку она работает после вызова addressError - поскольку эта функция не меняется, я знаю, что она работает Поэтому я могу только предположить, что проблема заключается в размещенных блоках.)

Если я генерирую данные без ошибок, скрипт выполняется просто отлично, поэтому я знаю, что при чтении данных из формы ошибок нет. Все переменные возвращаются на следующей странице без проблем.

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

Спасибо!

РЕДАКТИРОВАТЬ: Хорошо, ошибка, кажется, в моем HTML. Я не выяснил, что именно в скрипте вызывает ошибку, но в HTML все формы являются «input type = 'text' name = '[name]'», кроме поля адреса, которое является «input type =» text '"- эти лишние пробелы что-то напутали, понятно.

Спасибо тем, кто ответил терпеливо, и да, я переписал код, чтобы быть более внимательным с меньшими возможностями ошибок транскрипции.

-Tom

Ответы [ 2 ]

1 голос
/ 22 апреля 2011

В Python есть механизмы для динамического создания функций, которые полезны в подобных ситуациях. Одним из них является метакласс, который требует некоторого двойного косвенного мышления и может быть сложным для размышлений. Более простой (и ступенькой к окончательному изучению метаклассов) является замыкание, функция, которая создает функцию, определяя ее локально, а затем возвращая эту локальную функцию. Вот как вы можете использовать замыкание для генерации всех ваших функций check_xxx:

def check_field(fieldname, errorname, errormessage):
    def fn(user, formdata):
        if fieldname in formdata and formdata[fieldname].value != '':
            return formdata[fieldname].value
        else:
            feedback = {errorname : errormessage}
            stepTwoError(user, formdata, errorname, feedback)
    return fn

check_address = check_field("streetAddress", "blank_address", "Please enter a valid street address!")
check_city = check_field("city", "blank_city", "Please enter a city!")
check_state = check_field("state", "blank_state", "Please enter a state!")
check_zip = check_field("zip", "blank_zip", "Please enter a zip code!")

Замыкания отлично подходят для устранения кодирования при копировании и вставке, а также из-за частых ошибок, когда после вставки копии более ранней функции одна или несколько ссылок на имена переменных остаются неизменными по сравнению с оригиналом. Используя замыкание, вы можете быть намного увереннее в том, что ваши отдельные функции действительно являются действительными созданиями из исходного шаблона.

Но я согласен с @JohnMachin, я тоже подозреваю, что ваша ошибка действительно заключается в известном исправном методе, stepTwoError. Попробуйте оценить поля ввода в другом порядке. Имеет ли stepTwoError аргумент по умолчанию, который является изменяемым объектом или списком? Возможно, это предполагается пустым, но сохраняет значения предыдущего вызова? Или он обновляет глобальную переменную и оставляет ее в грязном состоянии, что приводит к ошибкам повторного вызова?

0 голосов
/ 22 апреля 2011

Эта "логика" ошибочна: "" "(Примечание: я не включаю функцию stepTwoError (), потому что я знаю, что она работает, так как она работает после вызова addressError - так как эта функция не изменяется,я знаю, что это работает ""

Все, что вы знаете, это то, что это работает, когда передано "blank_address" в качестве 3-го аргумента. Предположим, оно содержит

if third_arg != "blank_address":
    while 1:
        pass
...