tamus tamus - 1 month ago 14
Python Question

Can't get times back from python script

I am testing two python scripts, sunset.py which calls gettimes.py to get two times but I get nothing returned. I know gettimes.py is called as it prints the times but I can't print them from sunset.py
gettimes.py

from gettimes import main

arg1 = ''
arg2 = ''

main(arg1, arg2)

print 'Hour on ', arg1
print 'Hour off ', arg2


sunset.py

import ephem # to get sunrise and sunset
import datetime # import date and time modules
import time
import sys

def main(arg1, arg2):
here = ephem.Observer() #determine position of observer
here.lat = 'xx.xx085057'
here.lon = '-x.xx781850'
here.elevation = 43 #meters
sun = ephem.Sun() #define sun as object

arg1 = here.next_rising(sun).datetime().strftime('%H:%M')
arg2 = here.next_setting(sun).datetime().strftime('%H:%M')
print arg1, arg2

if __name__=='__main__':
sys.exit(main(sys.argv[1], sys.argv[2]))


What am I doing wrong?

Answer

Python does not pass arguments by reference the way you think it does (it's not like C++ reference semantics). It's more like passing by pointer; you can mutate attributes of the object received, but if you reassign the name completely, you've lost the pointer to the original object (and the local name no longer has anything to do with the caller).

When you reassign arg1 and arg2 in sunset.main, you rebound the local names, but the callers variables are unchanged. The usual solution here is to just return the new values, not pass in garbage when the function doesn't need it:

def main():
  here = ephem.Observer() #determine position of observer
  here.lat = 'xx.xx085057'
  here.lon = '-x.xx781850'
  here.elevation = 43 #meters
  sun = ephem.Sun() #define sun as object

  arg1 = here.next_rising(sun).datetime().strftime('%H:%M')
  arg2 = here.next_setting(sun).datetime().strftime('%H:%M')
  return arg1, arg2

# I have no idea why you were passing argv stuff to main here,
# since it's not used, but this is a not too terrible way of handling it:
if __name__ == '__main__':
    print(*main())

And on the caller side:

from gettimes import main

arg1, arg2 = main()

print 'Hour on ', arg1
print 'Hour off ', arg2