Handling 3 operands in an expression without raising an exception
Νίκος
nikos.gr33k at gmail.com
Sun Sep 29 07:14:24 EDT 2013
Στις 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.
More information about the Python-list
mailing list