Am 19.10.18 um 12:15 schrieb Steven D'Aprano:
On Fri, Oct 19, 2018 at 09:18:02AM +0200, Thomas Güttler wrote:
Imaging you are developing in the django context.
Everytime you use a variable named "request" or "response" your human brains knows that this is a subclass of django.http.HttpRequest and django.http.HttpResponse.
Not *my* human brain.
I know that I know nothing, or at least not much. My laptop does compute much faster than I do
I've seen far too many variables called (let's say) "mylist" which actually hold a dict or a tuple (or in one memorable case, a string!) to unconditionally believe the name.
But I'll accept that given the context, there's a very strong likelihood that a variable called "request" might be a HttpRequest object, and one called "response" might be a HttpResponse object.
Great, we agree here.
How to give the IDE this knowledge?
One solution is the do typehinting everywhere the veriable gets used.
You shouldn't need to. Your IDE or type-checker should be able to do type-inference and infer the type. You only need to add a hint if it cannot infer the type.
If your IDE doesn't do type inference, get a better IDE *wink*
I use the free community version of pyCharm, and it often does not know
which type a variable has. A simple name2type mapping would improve
the situation a lot.
But why does the human brain not need this?
Because it is intelligent?
I would not call this intelligence. There is a simple dictionary in the brain of the developer, which maps:
variable-name --> Type
Is that a fact? How do you know?
How does the information in this dict get filled in?
as I already said before a docstring in the __init__.py file would
be a pragmatic solution.
I think it is FAR more likely that it is intelligence: the human programmer understands the *meaning of the code* and would equally recognise that
myresponse response2 reply answer rspns
I try to use the same variable name again and again. I guess in my
code base in 95% an instance of HttpRequest is stored in a variable called "request".
You say: the human programmer understands the *meaning of the code*
Great if that is the case for you. I often look at the code and don't get it at all.
I wrote the lines two years ago, and today I don't understand why they exist.
This does not happen daily, but at least once a month.
In other words, we *read* and *understand* the code, not just mechanically map names to types. That's why we have no problem with dynamically typed languages like Python were the one name can refer to objects of many different types.
When the context is different, we interpret the name differently:
response = input("Continue? Y/n ") response = chatbot.lookup(question) response = mapping[challenge]
would all be interpreted differently, even if the module used Django. I doubt any reasonable programmer would imagine that they were HttpResponse objects.
relax. I mean this like I said. Please relax.
Imagine you have this: reposense = obj.get_response()
First: if the variable is the return value of a method, and the method
has type-annotated the return value, then this type information gets used.
End of type detect.
If the type information can't be found from the method, then use the name2type
mapping which I suggest in this mail.
And this mapping dict exists once per library.
Or more likely, doesn't exist at all.
If you are developing in the requests http lib, then there is a different mapping. Then "response" means type requests.Response.
What if you are using *both* django and requests in the same module? You could have both of these:
response = something_returning_requests_Response() response = something_returning_django_HttpResponse()
in the one module.
Do you really care for this edge-case? I don't.
The way to get the type info is the same: Check the method,
if it has it use this. Do not use name2type mapping. End of type detection.
Then check the current file or the above __init__.py of the code. Take
name2type mapping from there.