[Python] Strano comportamento del comando shell di Django.
Paolo Leggio
paolo a digitalmonkeys.it
Mar 17 Set 2019 15:44:28 CEST
Ciao a tutti, un piccolo rompicapo.
quando eseguo il comando shell di Django, ho un comportamento inaspettato dell' interprete python che proprio non riesco a spiegare:
Questo é il semplice snippet di codice che voglio eseguire:
Quando tento l’escussione con python manage.py shell < test.py ottengo un errore e non riesco a capire a che modulo python vengono associate le funzioni definite.
File test.py
def foo():
print('foo() --start--')
print('foo() --stop--')
def bar():
print('bar() --start--')
print('bar() --stop--')
def main():
print('main() ### start ###')
foo()
bar()
print('main() ### stop ###')
foo()
bar()
main()
Risultato aspettato:
foo() --start--
foo() --stop--
bar() --start--
bar() --stop--
main() ### start ###
foo() --start--
foo() --stop--
bar() --start--
bar() --stop--
main() ### stop ###
Se provo a eseguirlo passando il file come stdinput alla shell di Django, qualcosa nella gestione dei moduli non funziona e il codice non gira:
python manage.py shell < test.py
foo() --start--
foo() --stop--
bar() --start--
bar() --stop--
main() ### start ###
Traceback (most recent call last):
File "./manage.py", line 21, in <module>
main()
File "./manage.py", line 17, in main
execute_from_command_line(sys.argv)
File "/private/tmp/test/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/private/tmp/test/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/private/tmp/test/lib/python3.7/site-packages/django/core/management/base.py", line 323, in run_from_argv
self.execute(*args, **cmd_options)
File "/private/tmp/test/lib/python3.7/site-packages/django/core/management/base.py", line 364, in execute
output = self.handle(*args, **options)
File "/private/tmp/test/lib/python3.7/site-packages/django/core/management/commands/shell.py", line 95, in handle
exec(source)
File "<string>", line 17, in <module>
File "<string>", line 11, in main
NameError: name 'foo' is not defined
Se lo eseguo passandolo com stdinput direttamente a python funziona tutto, le nuove funzioni vengono inserite nel modulo __main__ <module '__main__' (built-in)>
python < test.py
Il codice del comando shell di Django, é molto semplice:
dopo aver fatto il bootstrap del progetto Django, non fa altro che
exec(sys.stdin.read())
Provando a mano,
Se lancio la shell di Django in modalitá interattiva
python manage.py shell
Metto i sorgenti in una stringa e la eseguo con exec() un po come fa il comando shell, funziona tutto
Python 3.7.4 (default, Sep 7 2019, 18:27:02)
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> source_code = '''
... def foo():
... print('foo() --start--')
... print('foo() --stop--')
...
... def bar():
... print('bar() --start--')
... print('bar() --stop--')
...
... def main():
... print('main() ### start ###')
... foo()
... bar()
... print('main() ### stop ###')
...
... foo()
... bar()
... main()
... '''
>>>
>>> exec(source_code)
foo() --start--
foo() --stop--
bar() --start--
bar() --stop--
main() ### start ###
foo() --start--
foo() --stop--
bar() --start--
bar() --stop--
main() ### stop ###
>>>
Cosa succede quando passo nel comando shell di Django?
Ciao a tutti.
-------------- parte successiva --------------
Un allegato HTML è stato rimosso...
URL: <http://lists.python.it/pipermail/python/attachments/20190917/004e205f/attachment.html>
Maggiori informazioni sulla lista
Python