Python, эквивалентный из компактного PHP's () и извлечение ()

Спасибо всем за ваш вклад, но проблема была в другом. Это было то, что я устанавливал печенье после того, как мои заголовки были отправлены. Теперь это не значит, что мне нужно было установить cookie в верхней части моего файла, но у меня были некоторые комментарии и пробелы в верхней части моего файла, и удаление этих файлов позволило избавиться от ошибки заголовков. Если удаление пробелов не устраняет ошибку заголовков, попробуйте использовать ob_start() перед установкой файла cookie и ob_end_flush(); после. Но это не лучшая практика.

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

$username = isset(

Спасибо всем за ваш вклад, но проблема была в другом. Это было то, что я устанавливал печенье после того, как мои заголовки были отправлены. Теперь это не значит, что мне нужно было установить cookie в верхней части моего файла, но у меня были некоторые комментарии и пробелы в верхней части моего файла, и удаление этих файлов позволило избавиться от ошибки заголовков. Если удаление пробелов не устраняет ошибку заголовков, попробуйте использовать ob_start() перед установкой файла cookie и ob_end_flush(); после. Но это не лучшая практика.

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

[110]POST['username']) ?

Спасибо всем за ваш вклад, но проблема была в другом. Это было то, что я устанавливал печенье после того, как мои заголовки были отправлены. Теперь это не значит, что мне нужно было установить cookie в верхней части моего файла, но у меня были некоторые комментарии и пробелы в верхней части моего файла, и удаление этих файлов позволило избавиться от ошибки заголовков. Если удаление пробелов не устраняет ошибку заголовков, попробуйте использовать ob_start() перед установкой файла cookie и ob_end_flush(); после. Но это не лучшая практика.

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

[110]POST['username'] : ''; $enterpass = isset(

Спасибо всем за ваш вклад, но проблема была в другом. Это было то, что я устанавливал печенье после того, как мои заголовки были отправлены. Теперь это не значит, что мне нужно было установить cookie в верхней части моего файла, но у меня были некоторые комментарии и пробелы в верхней части моего файла, и удаление этих файлов позволило избавиться от ошибки заголовков. Если удаление пробелов не устраняет ошибку заголовков, попробуйте использовать ob_start() перед установкой файла cookie и ob_end_flush(); после. Но это не лучшая практика.

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

[110]POST['password']) ?

Спасибо всем за ваш вклад, но проблема была в другом. Это было то, что я устанавливал печенье после того, как мои заголовки были отправлены. Теперь это не значит, что мне нужно было установить cookie в верхней части моего файла, но у меня были некоторые комментарии и пробелы в верхней части моего файла, и удаление этих файлов позволило избавиться от ошибки заголовков. Если удаление пробелов не устраняет ошибку заголовков, попробуйте использовать ob_start() перед установкой файла cookie и ob_end_flush(); после. Но это не лучшая практика.

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

[110]POST['password'] : '';
9
задан Turadg 9 September 2009 в 20:21
поделиться

5 ответов

It's not very Pythonic, but if you really must:

import inspect

def compact(*names):
    caller = inspect.stack()[1][0] # caller of compact()
    vars = {}
    for n in names:
        if n in caller.f_locals:
            vars[n] = caller.f_locals[n]
        elif n in caller.f_globals:
            vars[n] = caller.f_globals[n]
    return vars

def extract(vars):
    caller = inspect.stack()[1][0] # caller of extract()
    for n, v in vars.items():
        caller.f_locals[n] = v   # NEVER DO THIS - not guaranteed to work

I've used these implementations quite a bit, and they work, but technically modifying f_locals is not supported.

Seriously though, if you really feel you have a need to use these functions, you're probably doing something the wrong way. It seems to run against Python's philosophy on at least three counts: "explicit is better than implicit", "simple is better than complex", "if the implementation is hard to explain, it's a bad idea", maybe more (and really, if you have enough experience in Python you know that stuff like this just isn't done). I could see it being useful for a debugger or post-mortem analysis, or perhaps for some sort of very general framework that frequently needs to create variables with dynamically chosen names and values, but it's a stretch.

If you are going to use these functions, you should at least keep the extracted variables contained to within small scopes. Wrap them in functions that you can then consider to be "black boxes". The main reason extract is bad is that it puts variables in your symbol table in a way that isn't clear from inspecting the code. If you keep the effects of those variables localized to a very small function, and explain what you're doing with clear code and comments, it's not that big of a problem.

10
ответ дан 4 December 2019 в 07:15
поделиться

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

>>> def compact(locals, *keys):
...     return dict((k, locals[k]) for k in keys)
...
>>> a = 10
>>> b = 2
>>> compact(locals(), 'a', 'b')
{'a': 10, 'b': 2}

>>> def extract(locals, d):
...     for k, v in d.items():
...         locals[k] = v
...
>>> extract(locals(), {'a': 'foo', 'b': 'bar'}
>>> a
'foo'
>>> b
'bar'

Тем не менее, я не думаю, что эти функции «чрезвычайно удобны». Динамические глобальные / локальные переменные являются злыми и подверженными ошибкам - ребята из PHP узнали об этом, когда не одобряли register_globals. По моему опыту, немногие опытные программисты PHP или основные фреймворки используют compact () или extract () .

В Python явное лучше, чем неявное :

a = 1
b = 2
# compact
c = dict(a=a, b=b)

# extract
a, b = d['a'], d['b']
9
ответ дан 4 December 2019 в 07:15
поделиться

Is it worth pointing out that extract() (and to a lesser extent, compact()) is one of the most "evil" features of PHP (along with register_globals and eval), and should be avoided?

extract makes it much harder to determine where a variable was defined. When it is harder to trace a variable back to where it was defined, it's harder to check for common security problems like using uninitialized variables, or unfiltered variables which originated from user input.

compact is not as bad, but if used badly can still make it more difficult than it would otherwise be to see where an array member gets set from a variable.

The equivalent of extract() in many other languages is the with keyword. Python now has a with keyword, though it works a bit differently, making it not quite like extract(). However, in other languages such as Javascript, the with keyword also has a poor reputation.

I think the best advice would be to think differently - instead of trying to emulate a bad feature of PHP, think of other ways to do what you want to do with concise and readable code.

6
ответ дан 4 December 2019 в 07:15
поделиться

Я предполагаю, что эквивалент extract ($ x) равен globals (). Update (x) , как и для compact () это подмножество vars ()

>>> foo, bar, baz = 1, 2, 3
# extract
>>> globals().update({"foo": 4, "qux": 5})
>>> foo
4
>>> qux
5
# compact
>>> d = dict((k, v) for k, v in vars().iteritems() if k in ["foo", "bar"])
>>> d
{'bar': 2, 'foo': 1}
2
ответ дан 4 December 2019 в 07:15
поделиться

PHP's compact function in Python (works with 2.6; not guaranteed to work with earlier versions of Python):

import inspect
def compact(*args):
    return dict([(i, inspect.currentframe().f_back.f_locals.get(i, None)) 
                  for i in args])

I've written more extensively about this: Python can be just as ugly as PHP.

3
ответ дан 4 December 2019 в 07:15
поделиться
Другие вопросы по тегам:

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