On Thu, Jan 30, 2020 at 07:17:34PM -0000, Johan Vergeer wrote: > It is a couple of days later, but I managed to create a more expanded > proposal. > > This proposal is about having a simple and consistent way of getting the name > of an object. > Whether it is a class, type, function, method or variable or any other object.
Variables are not objects, and in Python, there are two distinct meanings for "name": (1) "Names" in the sense of name bindings like `spam = expression`. In this sense, objects can have zero, one or more names: # this string has (at least) three names spam = eggs = cheese = "Hello world!" but the *name* "spam" is not an object or a first-class value at all. (2) Some objects, like modules, classes, functions and methods, have a special dunder `__name__` attribute. When people talk about the name of a module, class, function or method, that's what they expect, and that's what they see in the object repr. Most objects have no such concept of a name in sense (2), and most objects are not bound to a name in sense (1). Objects which have both may not agree: def spam(): pass eggs = spam del spam What is the name of the function object bound to the "eggs" name? Should it be "eggs" or "spam"? [...] > To be honest, I am a big fan of IDEs, like PyCharm, which have great > refactoring tools, but it doesn't refactor strings. You should report that to the IDEs as a feature request. > ## Usage in comparisons > > Another situation is when you want to do a comparison. An example of this > would be: > > ```python > def my_factory(class_name: str): > if class_name == "Foo": > return Foo() > if class_name == "Bar": > return Bar() > ``` If I saw that code in production, I would strongly suspect that the author isn't very experienced with Python or is trying to write Java (or equivalent) code in Python. There are exceptions, of course, such as if you are getting the class name from user data at runtime. But normally that would be better written as: def my_factory(cls: type): return cls() (This is a toy. In real code, the my_factory() function better do something useful to justify its existence.) > I know this is a very simple example that can be solved with the > example below, but it would be nice if we can do the same with > methods, functions and attributes. > > ```python > def my_factory(class_name: str): > if class_name == Foo.__name__: > return Foo() > if class_name == Bar.__name__: > return Bar() > ``` In your earlier example, your sense of "name" is that of name bindings. In this example, your sense of "name" is the object's internal name. These are two different, distinct and independent concepts. > From the messages in this thread I concluded there is some confusion > about what I would like to achieve with this proposal. In this part I > will try to make it more clear what the behavior would be. For now > I'll stick to the C# naming `nameof()`. > > ## Class names > > When you want to get the name of a class, you should just use the name. So > `nameof(Foo)` becomes `"Foo"` and `nameof(type(foo))` also becomes `"Foo"`. > The results are basically the same as `Foo.__name__` and `type(foo).__name__`. Spoken like somebody who is not used to languages where classes are first-class values. for obj in (Foo, Bar, Baz): print(nameof(obj)) Should that print "obj", "obj", "obj" or "Foo", "Bar", "Baz"? Trick question! Actually I did this earlier: Foo, Bar, Baz = Spam, Eggs, Cheese so perhaps it should print "Spam", "Eggs", "Cheese" instead. How does the nameof() function know which answer I want? The same applies to functions, modules and methods. -- Steven _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/OXIOLKAUXIWJNPA2BAIZLXN35DBEJ77L/ Code of Conduct: http://python.org/psf/codeofconduct/