I’m not sure if this has come up before, but I couldn’t find it when I searched.
I’m throwing out the idea that f-strings could be use on attribute lookup for dynamic names.
So instead of this:
getattr(some_instance, name)
You could do:
some_instance.{name}
Or any other valid f-string expression (not the format specifiers)
some_instance._group{num + 1}
some_instance.{get_next_name()}
It could potentially be extended to cover the default, something like
some_instance.{name:default_value}
I’ll admit this is sugar and any performance gain from eliminating the call to getattr()
is marginal. Readability is subjective, but some_instance.{name1}.{name2}
seems more readable to me than getattr(getattr(some_instance, ‘name1’), ‘name2’)
.
Of course this would require updating the parser and lookup logic. And we’d need to determine if nested dynamic lookups would be supported:
some_instance.{ name.{sub_name} }
Just an idea, because even if this one ends up in the bin, maybe it inspires the next great idea. Try not to be too harsh
Edit 1:
Changed title from “F-Strings as attributes“ to “Alternative Syntax for Attribute Access“ to better reflect the spirit of the proposal rather than the initial concept. Author’s note added below.
Author’s Note:
It seems my initial idea wasn’t communicated as clearly as I thought, and that has led to some alternatives that may be improvements. In my initial idea, anything after or between dots was to be parsed as an f-string, but I only gave one concrete example of this, some_instance._group{num + 1}
. Some interpreted the syntax as object.{…}
, where …
is a stand in for code to be evaluated. The result of the evaluated code would need to be a string. This is likely clearer and easier to implement. @blhsing then suggested removing the dot, object{…}
, so the syntax is similar to the way square brackets are used for indexing. Perhaps this is even clearer. Here are some examples of each:
Option A: Everything after or between dots can be interpreted as an f-string
some_instance.{name}, some_instance.{‘some_string’}, some_instance.group{num + 1}, some_instance.{name1}.{name2}
Option B: If the contents after or between the dots is enclosed in curly braces, it’s evaluated
some_instance.{name}, some_instance.{‘some_string’}, some_instance.{f’group{num + 1}'}, some_instance.{name1}.{name2}
Option C: No dot is used and curly braces are used for attribute access similarly to how square brackets are used for indexing
some_instance{name}, some_instance{‘some_string’}, some_instance{f’group{num + 1}'}, some_instance{name1}{name2}