4 votos

¿Por qué Arcpy está sobrescribiendo datetime en __main__? ¿Cómo lo arreglo sin reorganizar mis importaciones?

Considere los siguientes scripts:

import_test1.py:

from datetime import datetime
print(u'{}: {}'.format(__name__, datetime))
import import_test2
print(u'{}: {}'.format(__name__, datetime))
from datetime import datetime
print(u'{}: {}'.format(__name__, datetime))

import_test2.py:

from datetime import datetime
print(u'{}: {}'.format(__name__, datetime))
import arcpy
print(u'{}: {}'.format(__name__, datetime))
from datetime import datetime
print(u'{}: {}'.format(__name__, datetime))

Al ejecutar esta secuencia de comandos, se puede ver que arcpy es

C:\temp>py -2 .\import_test1.py
__main__: <type 'datetime.datetime'>
import_test2: <type 'datetime.datetime'>
import_test2: <type 'datetime.datetime'>
import_test2: <type 'datetime.datetime'>
__main__: <module 'datetime' (built-in)>
__main__: <type 'datetime.datetime'>

Este es un MCVE. (Me encontré con el problema de una manera más compleja, pero esto es suficiente para reproducir el comportamiento.)

Como se puede ver, la importación arcpy (no haciendo un from arcpy import *, sólo una llanura import arcpy) es la sobreescritura de mi módulo de importación cuando se trata de la __main__ script. Sustituye el tipo me importados con el módulo del mismo nombre, que no es lo que necesito.

Sé que es arcpy porque puedo reproducir con un simple script:

from datetime import datetime
print(u'{}: {}'.format(__name__, datetime))
import arcpy
print(u'{}: {}'.format(__name__, datetime))
from datetime import datetime
print(u'{}: {}'.format(__name__, datetime))

Da:

C:\temp>py -2 .\import_test.py
__main__: <type 'datetime.datetime'>
__main__: <module 'datetime' (built-in)>
__main__: <type 'datetime.datetime'>

No quiero reordenar mi módulos porque quiero seguir PEP8 directrices del orden de las importaciones: la biblioteca estándar, tercero, la aplicación local/biblioteca específica de las importaciones. Esto también es difícil de manejar si algún otro módulo realiza la importación de arcpy, como en mi módulo de dos ejemplo.

¿Cómo puedo obtener arcpy para detener la sobreescritura de variables que no pertenecen a ella? ¿Por qué es incluso haciendo esto en primer lugar?

2voto

Antonio Haley Puntos 2588

El arcpy los desarrolladores pueden distribuir una versión modificada del datetime con arcpy, uno con correcciones de errores, y puede ser monkeypatching la __main__ de espacio de nombres en la importación de arcpy. He aquí un ejemplo de cómo funciona.

El módulo de mypy, a continuación, importa el sistema operativo del módulo (con el nombre os) y, a continuación, vuelve a asignar __main__.datetime el valor de os (el sistema operativo del módulo).

# mypy.py:

import __main__
import os

__main__.datetime = os

Si vamos a importar mypy después de la importación, datetime, se "fija" de nuestro código.

>>> from datetime import datetime
>>> repr(datetime)
"<type 'datetime.datetime'>"
>>> import mypy
>>> repr(datetime)
"<module 'os' from '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>"

No está mal hacer esto. A veces, usted realmente necesita parche aguas arriba de código. El problema con Python datetime módulo es que el módulo y el nombre de la clase son los mismos y no son diferentes de uso de modismos: import datetime; datetime.datetime() vs from datetime import datetime; datetime(). Parece que arcpy parches de la primera y se rompe el segundo.

El cambio a import datetime y llamando datetime.datetime() en todo el código que utiliza arcpy debe ser una buena solución.

1voto

user8548 Puntos 188

Probablemente la forma más sencilla de solucionarlo es alias el tipo con otro nombre:

 # We have to alias the class because arcpy overwrites datetime in __main__
from datetime import datetime as DateTime
print(u'{}: {}'.format(__name__, DateTime))
import arcpy
print(u'{}: {}'.format(__name__, DateTime))
 

La otra alternativa es rodar con la modificación de las variables de su módulo de arcpy :

 # We have to use datetime directly because arcpy overwrites datetime in __main__
import datetime
print(u'{}: {}'.format(__name__, datetime))
import arcpy
print(u'{}: {}'.format(__name__, datetime))
 

No tengo idea de por qué arcpy comporta de esta manera.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X