Στις 29/9/2013 2:04 μμ, ο/η Jussi Piitulainen έγραψε:
Steven D'Aprano writes:

On Sun, 29 Sep 2013 12:35:17 +0300, Jussi Piitulainen wrote:

try:
   ...
except socket.gaierror as e:
   # watch out, a composition of bad advice (on demand) city, host = (
   ('city' in locals() or "blabla"),
                  ('host' in locals() or "blablabla") )

Bad advice, and buggy as well.

py> city = "New New York"
py> ('city' in locals() or "Blah blah")
True

Oh man, can you imagine Nikos trying to debug that?

Thanks. Sorry. This hurts. I didn't mean it to be buggy.

Let's see. The task is to assign a default value to city and host, if
they haven't a value yet; on one line (which I take to mean one
statement); in an "except" block where we may not know which
assignment failed in the "try" block; without "if"; but "or" is
allowed.

But the logic I was trying to implement is

city, host = ( (city if 'city' in locals() else "default city"),
                (host if 'host' in locals() else "default host") )

which uses an "if". The old tricks of using "or" and stuff for this
would surely go too far.

I know!

city, host = ( locals().get('city', "default city"),
                locals().get('host', "default host") )

I tend to like this: I might use it because it is a clear way to tell what var failed in the try clause and default it to soemthing.


Testing if the variables only exists when actually assigned:

  >>> def foo(x, y):
  ...    if x: foo = None
  ...    if y: bar = "bar"
  ...    return locals()
  ...
  >>> foo(False, False)
  {'y': False, 'x': False}
  >>> foo(False, True)
  {'y': True, 'x': False, 'bar': 'bar'}

Seems so.

What a monster, though. I don't even want to know if this, too, is
buggy in some way. It looks fragile.

Nikos, don't do this. The way to test if an assignment failed is to
use a try-catch. The way to know which one failed is to put each in
its own try-catch.

Dave's way though seems better.
Assign the vars default string and if they get re-assinged correctly that would be ideal, otherwise we have already given them the defaults.

ipval = ( os.environ.get('HTTP_CF_CONNECTING_IP') or os.environ.get('REMOTE_ADDR', "Cannot Resolve") )
city = "Άγνωστη Πόλη"
host = "Άγνωστη Προέλευση"
try:
        gi = pygeoip.GeoIP('/usr/local/share/GeoIPCity.dat')
        city = gi.time_zone_by_addr( ipval )
        host = socket.gethostbyaddr( ipval ) [0]
except Exception as e:
print( "metrites.py => (%s): " % lastvisit, repr( sys.exc_info() ), file=open('/tmp/err.out', 'w') )

I'll think i'll stick to this solution.

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to