__No__
|
|
|
|
|
Рег.: 17.01.2005
|
Сообщений: 21063
|
Из: Внутренняя Монголия
|
Рейтинг: 6310
|
|
[py] забавно
09.04.2008 13:43
|
|
|
Что-то такое имхо можно спрашивать на собеседовании:
code:
foo = 'a'
def fn():
print foo
# foo = 'b'
fn()
Не запуская, сказать: Что выдаст такой скрипт? Что выдаст такой скрипт, если раскомментировать строчку? (И главное, где )
Для меня было новостью
|
Dixi. |
|
fut
|
|
|
|
|
Рег.: 09.02.2008
|
Сообщений: 775
|
|
Рейтинг: 1653
|
|
|
Куда хоть собеседование было? И на какую должность?
|
|
__No__
|
|
|
|
|
Рег.: 17.01.2005
|
Сообщений: 21063
|
Из: Внутренняя Монголия
|
Рейтинг: 6310
|
|
Re: [py] забавно
[re: fut]
09.04.2008 14:57
|
|
|
Да не было никакого, просто такая вроде бы простая вещь: есть у питона внутреннее представление, и там он не совсем скриптовый.
А простую вещь где еще спрашивать ![:)](/images/graemlins/smile.gif)
P.S. То бишь сам нашел
|
Dixi. |
|
burivuh
|
Carpal Tunnel
|
|
|
|
Рег.: 08.08.2004
|
Сообщений: 4452
|
|
Рейтинг: 1567
|
|
|
В ответ на:
foo = 'a' def fn(): print foo global foo foo = 'b' fn()
Сработает... А что такое "не совсем скриптовый"?
|
Послушай, иногда мужчинам... нужно уважение иметь лицо (с) Безымянный переводчик |
|
__No__
|
|
|
|
|
Рег.: 17.01.2005
|
Сообщений: 21063
|
Из: Внутренняя Монголия
|
Рейтинг: 6310
|
|
|
Quote:
Сработает
Да я знаю как сработает. Проблема не в "как написать" ![:)](/images/graemlins/smile.gif) Если code:
def main():
foo = True
def fn():
foo = False
fn()
И global не поможет, поможет [True], например. Тут дело становится в типе и связывании. global еще и некошерный
Не совсем скриптовый - значит "вперед" подсматривает. Обычно же в документации рассказывают про line физические и логические, мол скрипт по строкам выполняется.
|
Dixi. |
|
burivuh
|
Carpal Tunnel
|
|
|
|
Рег.: 08.08.2004
|
Сообщений: 4452
|
|
Рейтинг: 1567
|
|
|
Ну, это вопрос скорее области видимости и closures. Вроде бы везде "обсосан" ![:D](/images/graemlins/laugh.gif) А про скриптовость... думаю, большинство байткодовых скриптовых языков такие
|
Послушай, иногда мужчинам... нужно уважение иметь лицо (с) Безымянный переводчик |
|
__No__
|
|
|
|
|
Рег.: 17.01.2005
|
Сообщений: 21063
|
Из: Внутренняя Монголия
|
Рейтинг: 6310
|
|
|
Quote:
Ну, это вопрос скорее области видимости и closures.
code:
def first():
foo = True
def fn():
foo = False
fn()
print foo
def second():
foo = [True]
def fn():
foo[0] = False
fn()
print foo
области видимости отличаются?
Quote:
большинство байткодовых скриптовых языков такие
Я не знал Ну и пример простой, мне понравился.
|
Dixi. |
|
burivuh
|
Carpal Tunnel
|
|
|
|
Рег.: 08.08.2004
|
Сообщений: 4452
|
|
Рейтинг: 1567
|
|
|
Ну, проблема касается именно локальных переменных. Поэтому область видимости. А проблема в оптимизации локальных переменных на этапе генерации байткода. Проблема известна давно, еще в python warts описана.
|
Послушай, иногда мужчинам... нужно уважение иметь лицо (с) Безымянный переводчик |
|
Orgasmatron
|
|
|
|
|
Рег.: 27.12.2003
|
Сообщений: 662
|
Из: north
|
Рейтинг: 27
|
|
|
Quote:
А проблема в оптимизации локальных переменных на этапе генерации байткода.
Не вижу тут проблемы в оптимизации локальных переменных на этапе генерации байткода
Quote:
Each occurrence of a name in the program text refers to the binding of that name established in the innermost function block containing the use.
If the definition occurs in a function block, the scope extends to any blocks contained within the defining one, unless a contained block introduces a different binding for the name.
The following constructs bind names: ... and targets that are identifiers if occurring in an assignment, for loop header, or in the second position of an except clause header.
Each assignment or import statement occurs within a block defined by a class or function definition or at the module level (the top-level code block).
Это не проблема, это типа так язык устроен.
типа вот:
code:
>>> dis.dis (first)
...
3 6 LOAD_CONST 1 (<code object fn at 0x8a673c8, file "<pyshell#4>", line 3>)
9 MAKE_FUNCTION 0 # сделали функцию без параметров
12 STORE_FAST 1 (fn)
5 15 LOAD_FAST 1 (fn)
18 CALL_FUNCTION 0
21 POP_TOP
...
>>> dis.dis (second)
2 0 LOAD_GLOBAL 0 (True)
3 BUILD_LIST 1
6 STORE_DEREF 0 (foo)
3 9 LOAD_CLOSURE 0 (foo)
12 BUILD_TUPLE 1 # типа одна свободная переменная
15 LOAD_CONST 1 (<code object fn at 0x8a72188, file "<pyshell#7>", line 3>)
18 MAKE_CLOSURE 0 # сделали замыкание без параметров
21 STORE_FAST 0 (fn)
...
>>>
оптимизация не при чем, вроде.
Редактировал Orgasmatron (10.04.2008 16:02)
|
<challenge>What food do you dislike the most?</challenge><answer salt="9rOeCp |
|
burivuh
|
Carpal Tunnel
|
|
|
|
Рег.: 08.08.2004
|
Сообщений: 4452
|
|
Рейтинг: 1567
|
|
|
Называй как хочешь. Я это называю оптимизацией, так как байт-код компилятор делает предположения на основе анализа всего блока кода, даже того, который к моменту выполнения определенных команд еще не выполнится. В ответ на:
Python's source-to-bytecode compiler tries to optimize accesses to local variables. It decides that a variable is local if it's ever assigned a value in a function. Without the assignment i = i + 1, Python would assume that i is a global and generate code that accessed the variable as a global at the module level. When the assignment is present, the bytecode compiler generates different code that assumes i is a local variable; local variables are assigned consecutive numbers in an array so they can be retrieved more quickly.
|
Послушай, иногда мужчинам... нужно уважение иметь лицо (с) Безымянный переводчик |
|
__No__
|
|
|
|
|
Рег.: 17.01.2005
|
Сообщений: 21063
|
Из: Внутренняя Монголия
|
Рейтинг: 6310
|
|
|
Вы вроде про разное, ты про первый кусочек кода говоришь, а Orgasmatron - про последний.
Эти кусочки про разное: первый про разбор кода функции, про который как раз я не знал, и про что ты привел цитату второй про naming, который как раз везде разбирается и рассказывается.
|
Dixi. |
|
__No__
|
|
|
|
|
Рег.: 17.01.2005
|
Сообщений: 21063
|
Из: Внутренняя Монголия
|
Рейтинг: 6310
|
|
|
Продолжение (это правда совсем для детского сада):
code:
~/test fvv$ cat foo.py
import bar
print 'foo'
~/test fvv$ cat bar.py
import foo
print 'bar'
Что выдаст: code: ~/test fvv$ python foo.py
и что code: ~/test fvv$ python
>>> import foo
|
Dixi. |
|
burivuh
|
Carpal Tunnel
|
|
|
|
Рег.: 08.08.2004
|
Сообщений: 4452
|
|
Рейтинг: 1567
|
|
|
|
Fj_
|
Carpal Tunnel
|
|
|
|
Рег.: 12.09.2004
|
Сообщений: 8795
|
|
Рейтинг: 3287
|
|
|
А объясни или дай ссылку на объяснение того, почему так, пожалуйста!
|
The data is the error (c)IIS FTP Server. |
|
__No__
|
|
|
|
|
Рег.: 17.01.2005
|
Сообщений: 21063
|
Из: Внутренняя Монголия
|
Рейтинг: 6310
|
|
Re: [py] забавно
[re: Fj_]
25.04.2008 17:05
|
|
|
Если запускаешь скрипт из командной строки, то у него __name__ == "__main__".
При импорте модуль много раз не импортируется, интерпретатор хранит список импортированных модулей и импортирует только если в списке модуля еще нет.
В первом случае в списке нет foo, есть __main__, вот он foo и импортирует второй раз. Во втором случае оба модуля нормальным образом оказываются в списке, импортируются по одному разу.
Как-то так ![:)](/images/graemlins/smile.gif)
|
Dixi. |
|
Kai
|
|
|
|
|
Рег.: 25.10.2002
|
Сообщений: 8251
|
|
Рейтинг: 818
|
|
|
code: class ClassAddMixin:
def _add(self, other):
self.__dict__.update(other.__dict__)
return self
__add__ = classmethod(_add)
class A(ClassAddMixin):
def f(self):
print "A.f"
class B(ClassAddMixin):
def g(self):
print "B.g"
AB = A + B
# AB = A.__add__(B)
ab = AB()
ab.f()
ab.g()
А почему вот эта штука не работает?
Quote:
TypeError: unsupported operand type(s) for +: 'classobj' and 'classobj'
Если сложение убрать и раскомментировать следующую строку, то все ок. Есть какие-то особенности перегрузки операторов в classobj?
|
|
chunky_bacon
|
chunky_bacon
|
|
|
|
Рег.: 08.10.2006
|
Сообщений: 1996
|
|
Рейтинг: 820
|
|
Re: [py] забавно
[re: Kai]
25.04.2008 19:14
|
|
|
Если ты хочешь складывать классы оператором +, объяви __add__ в их метаклассе.
|
|
burivuh
|
Carpal Tunnel
|
|
|
|
Рег.: 08.08.2004
|
Сообщений: 4452
|
|
Рейтинг: 1567
|
|
Re: [py] забавно
[re: Fj_]
25.04.2008 19:27
|
|
|
мое до исправления: В ответ на:
Для каждого модуля есть понятие import time code - код, работающий при импорте. Сюда входит все, что описано вне классов/функций + создание классов/функций по их описаниям. Этот код выполняется единожды при первом импорте модуля. В случае запуска модуля как скрипта, импорт этого модуля не выполняется. Поэтому там по два вывода при импорте в интерпретаторе и три при запуске как скрипт. А порядок вывода определяется порядком первого импорта и вложенностью. Ну банально, короче.
На самом деле: В ответ на:
Для каждого модуля есть понятие initialization code. Сюда входит все, что описано вне классов/функций. Этот код выполняется единожды при первом импорте модуля. В случае запуска модуля как скрипта, импорт этого модуля не выполняется.
В последнем предложении я могу быть не прав. Я так и не смог выяснить, можно ли назвать создание __main__ модуля импортом. Впрочем, как мне уже намекнули, это религиозный вопрос.
Редактировал burivuh (25.04.2008 21:25)
|
Послушай, иногда мужчинам... нужно уважение иметь лицо (с) Безымянный переводчик |
|