getattr - Why does Python look for __members__ rather than the requested field? -
i have class defines own __getattr__() in order interact xml tree instantiated objects contain. hides xml structure user , allows him set tag values, etc. if normal fields on object , works fine fields except one: 1 named field. here's how looks:
>>> q = myquery() >>> q.file = "database" >>> print(q) <?xml version="1.0" encoding="utf-8" standalone="yes"?> <requestcollection xmlns="http://dwd.de/sky"> <read> <select> <referencedate> <value></value> </referencedate> </select> <transfer> <file name="my file"/> </transfer> </read> </requestcollection> >>> q.file that works fine, side effects should happen so. if try set field field, string method shouldn't returning. clarity, simplified version of __getattr__:
def __getattr__(self, key): logging.info("looking value key {}.".format(key)) if key == "something" return self.method_with_side_effect(key) if key in field_list: logging.info("key in field list.") return self.other_method_with_side_effects(key) ensemble_member , field both in field_list. check out:
>>> q = myquery() >>> q.ensemble_member looking value key __members__. looking value key __methods__. looking value key ensemble_member. key in field list. ... side effects ... >>> q.field 'station' looking value key __members__. looking value key __methods__. the behavior ensemble_member correct, field it's totally incorrect. why that?
i have no methods nor class / object members named field.
another interesting thing is, if put on first line of __getattr__:
def __getattr__(self, key): if key == "field": raise valueerror the following still happens:
>>> q = myquery() >>> q.field 'station' looking value key __members__. looking value key __methods__. what's going on?
i've got - offending code was, in end, these lines:
class skyquery(object): _unique_fields = ["parameter", "ensemble", "forecast", "station"] _field_tag_values = [field + "_value" field in _unique_fields] naming temporary variable "field" in list comprehension causing problem. python retaining after done. behavior consistent, wasn't expecting it.
i see 3 solutions here (the third suggested user4815162342). implemented third.
rename temporary variable
xratherfield. still havextemporary variable floating around in code, because no members should calledxdoesn't bother me.call
del(field)delete field. don't callingdel(), thought clutter code, work if needed able access variable later on.replace list comprehension generator expression
list(field + "_value" field in _unique_fields)not share problem
Comments
Post a Comment