Каков объем принявшего значение по умолчанию параметра в Python?

Вы говорите о двух разных вещах: «проверка HTML5» и проверка формы HTML с помощью javascript / jquery.

HTML5 имеет встроенные опции для проверки формы. Например, использование «обязательного» атрибута в поле, которое может (на основе реализации браузера) не отправлять форму без использования javascript / jquery.

С помощью javascrip / jquery вы можете сделать что-то вроде этого

$('your_form_id').bind('submit', function() {
   // validate your form here
   return (valid) ? true : false;
});
25
задан charlie 25 February 2010 в 05:26
поделиться

7 ответов

Область применения такая, как вы и ожидали.

Возможно, удивительно то, что значение по умолчанию вычисляется только один раз и используется повторно, поэтому при каждом вызове функции вы получаете один и тот же список, а не новый список, инициализированный в [].

Список хранится в f.func_defaults.

def f(a, L=[]):
    L.append(a)
    return L

print f(1)
print f(2)
print f(3)
print f.func_defaults
f.func_defaults = (['foo'],) # Don't do this!
print f(4)

Result:

[1]
[1, 2]
[1, 2, 3]
([1, 2, 3],)
['foo', 4]
23
ответ дан 28 November 2019 в 21:37
поделиться

Там даже меньше "магии", чем вы могли бы подозревать. Это эквивалентно

m = []

def f(a, L=m):
    L.append(a)
    return L

print f(1)
print f(2)
print f(3)

m создается только один раз.

3
ответ дан Joe Koberg 28 November 2019 в 21:37
поделиться

«Проблема» в том, что L=[] оценивается только один раз , то есть, когда файл компилируется. Python просматривает каждую строку файла и компилирует его. К тому времени, когда он достигает def с параметром по умолчанию, он создает этот экземпляр списка один раз.

Если вы поместите L = [] в код функции, экземпляр не будет создан во «время компиляции» (фактически время компиляции также можно назвать частью времени выполнения), потому что Python компилирует код функции, но не вызывает его. Таким образом, вы получите новый экземпляр списка, потому что создание выполняется каждый раз, когда вы вызываете функцию (а не один раз во время компиляции).

Решением этой проблемы является не использование изменяемых объектов в качестве параметров по умолчанию, или только фиксированные экземпляры, такие как None:

def f(a, L = None):
    if l == None:
        l = []
    L.append(a)
    return L

Обратите внимание, что в обоих описанных вами случаях область действия L это область действия функции.

0
ответ дан AndiDog 28 November 2019 в 21:37
поделиться

Область видимости переменной L работает должным образом.

"Проблема" в списке, который вы создаете с помощью []. Python не создает новый список каждый раз, когда вы вызываете функцию. L получает один и тот же список при каждом вызове, поэтому функция «запоминает» предыдущие вызовы.

По сути, это то, что у вас есть:

mylist = []
def f(a, L=mylist):
    L.append(a)
    return L

В Руководстве по Python это изложено так :

Значение по умолчанию оценивается только один раз. Это имеет значение, когда по умолчанию используется изменяемый объект, такой как список, словарь или экземпляры большинства классов.

и предлагает следующий способ кодирования ожидаемого поведения:

def f(a, L=None):
    if L is None:
        L = []
    L.append(a)
    return L
6
ответ дан 28 November 2019 в 21:37
поделиться

Также возможно разрешить сервлетContextListener задавать свойства System:

import java.util.Enumeration;
import javax.servlet.*;

public class SystemPropertiesHelper implements
        javax.servlet.ServletContextListener {
    private ServletContext context = null;

    public void contextInitialized(ServletContextEvent event) {
        context = event.getServletContext();
        Enumeration<String> params = context.getInitParameterNames();

        while (params.hasMoreElements()) {
          String param = (String) params.nextElement();
          String value = 
            context.getInitParameter(param);
          if (param.startsWith("customPrefix.")) {
              System.setProperty(param, value);
          }
        }
    }

    public void contextDestroyed(ServletContextEvent event) {
    }
}

И затем поместить это в web.xml (должно быть возможно и для context.xml)

<context-param>
        <param-name>customPrefix.property</param-name>
        <param-value>value</param-value>
        <param-type>java.lang.String</param-type>
</context-param>

<listener>
    <listener-class>servletUtils.SystemPropertiesHelper</listener-class>    
</listener>

Это сработало для меня.

-121--861677-

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

-121--2434067-

Необходимо помнить, что питон является интерпретируемым языком. То, что происходит здесь, когда функция «f» определена, она создает список и присваивает его параметру по умолчанию «L» функции «f». Позднее при вызове этой функции в качестве параметра по умолчанию используется тот же список. Короче говоря, код в строке «def» исполняется только один раз при определении функции. Это обычный питон, из которого я впал в себя.

def f(a, L=[]):
    L.append(a)
    return L

print f(1)
print f(2)
print f(3)

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

def f(a, L=None):
    L = L or []
    L.append(a)
    return L

Это использует короткое замыкание или, чтобы либо взять переданный «L», либо создать новый список.

Ответ на вопрос области: «L» имеет только область действия в функции «f», но потому, что параметры по умолчанию назначаются одному списку только один раз вместо каждого вызова функции, которая ведет себя так, как если бы параметр по умолчанию «L» имел глобальную область действия.

-1
ответ дан 28 November 2019 в 21:37
поделиться

Допустим, у вас есть следующий код:

def func(a=[]):
    a.append(1)
    print("A:", a)

func()
func()
func()

Вы можете использовать отступы Python, чтобы понять, что происходит. Все, что находится на одном уровне с левым полем, выполняется при запуске файла. Все, что имеет отступ, компилируется в объект кода, который запускается при вызове func () . Таким образом, функция определена и ее аргументы по умолчанию устанавливаются один раз, когда программа запускается (поскольку оператор def находится на левом уровне).

Интересный вопрос, что он делает с аргументами по умолчанию. В Python 3 большая часть информации о функции размещается в двух местах: func .__ code __ и func .__ defaults __ . В python 2 func .__ code __ было func.func_code func .__ defaults __ было func.func_defaults . В более поздних версиях python 2, включая 2.6, есть оба набора имен, чтобы облегчить переход от python 2 к python 3. Я буду использовать более современные __ code __ и __ по умолчанию __ .Если вы застряли на более старом питоне, концепции останутся прежними; просто названия различаются.

Значения по умолчанию хранятся в func .__ defaults __ и извлекаются каждый раз при вызове функции.

Таким образом, когда вы определяете функцию выше, тело функции компилируется и сохраняется в переменных под __ code __ для выполнения позже, а аргументы по умолчанию сохраняются в __ defaults __ . Когда вы вызываете функцию, она использует значения из __ defaults __ . Если эти значения изменяются по какой-либо причине, для использования доступна только измененная версия.

Поиграйте с определением различных функций в интерактивном интерпретаторе и посмотрите, что вы можете узнать о том, как python создает и использует функции.

1
ответ дан 28 November 2019 в 21:37
поделиться

Объяснение дано в ответах на этот вопрос . Подведем итог:

Функции в Python - это своего рода объект. Поскольку они являются своего рода объектами, при создании экземпляров они действуют как объекты. Функция, если она определена с изменяемым атрибутом в качестве аргумента по умолчанию, в точности совпадает с классом со статическим атрибутом, который является изменяемым списком.

У Леннарта Регебро есть хорошее объяснение , и ответ на вопрос Роберто Лиффредо превосходен.

Чтобы адаптировать ответ Леннарта ... если у меня есть класс BananaBunch :

class BananaBunch:
    bananas = []

    def addBanana(self, banana):
        self.bananas.append(banana)


bunch = BananaBunch()
>>> bunch
<__main__.BananaBunch instance at 0x011A7FA8>
>>> bunch.addBanana(1)
>>> bunch.bananas
[1]
>>> for i in range(6):
    bunch.addBanana("Banana #" + i)
>>> for i in range(6):
    bunch.addBanana("Banana #" + str(i))

>>> bunch.bananas
[1, 'Banana #0', 'Banana #1', 'Banana #2', 'Banana #3', 'Banana #4', 'Banana #5']

// And for review ... 
//If I then add something to the BananaBunch class ...
>>> BananaBunch.bananas.append("A mutated banana")

//My own bunch is suddenly corrupted. :-)
>>> bunch.bananas
[1, 'Banana #0', 'Banana #1', 'Banana #2', 'Banana #3', 'Banana #4', 'Banana #5', 'A mutated banana']

Как это применимо к функциям? Функции в Python являются объектами . Это стоит повторить. Функции в Python являются объектами .

Итак, когда вы создаете функцию, вы создаете объект. Когда вы задаете функции изменяемое значение по умолчанию, вы заполняете атрибут этого объекта изменяемым значением, и каждый раз, когда вы вызываете эту функцию, вы работаете с одним и тем же атрибутом. Итак, если вы используете изменяемый вызов (например, append), то вы изменяете тот же объект, как если бы вы добавляли бананы к объекту bunch .

0
ответ дан 28 November 2019 в 21:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: