import module == from module import *?

2019-02-20 12:27发布

问题:

I had a problem with the Django tutorial so I asked a question here. No-one knew the answer, but I eventually figured it out with help from Robert. Python seems to be treating import datetime the same as from datetime import *.

Working code:

import datetime
from django.db import models

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    def __unicode__(self):
        return self.question

    def was_published_today(self):
        return self.pub_date.date() == date.today()

Not working code: (The only differences are the import statements and the last line.)

from django.db import models
import datetime

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    def __unicode__(self):
        return self.question

    def was_published_today(self):
        return (self.pub_date() == datetime.date.today())

EDIT: I guess I wasn't clear enough. The code produces the exact same traceback with the last line being return (self.pub_date.date() == datetime.date.today()) Me originally forgetting to add .date() is NOT the error I'm asking about.

The traceback produced by the not working code:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/myDir/mySite/polls/models.py", line 11, in was_published_today
    return (self.pub_date() == datetime.date.today())
TypeError: 'datetime.datetime' object is not callable

Why on earth is it doing this?

My question is NOT about forgetting .date(). My question is: Why is datetime in my namespace without me using from datetime import *.

Note: The first question asked what it was doing. This question asks why.

UPDATE: Suddenly it works. With datetime.date.today() AND date.today(). My question remains though, why does date.today() work? It seems datetime is in my local namespace without me putting there. Why?

回答1:

As we discussed in the comments, the problem is not with the code, but the way you are updating the source. python caches modules in sys.modules. You can reload individual modules using the reload function, but for many changes it's best to reload the entire shell. In many cases it looked as though the changes had propagated because the error messages seemed to have changed, this is because python doesn't cache the source code of the file, so when it references code, it shows you the newest version. Hopefully now, you can apply the other answers with more success.



回答2:

The problem in the latter snippet is with this part of your code:

return (self.pub_date() == datetime.date.today())

self.pub_date contains a datetime.datetime instance. It's not callable like that. For example:

>>> import datetime
>>> d = datetime.datetime.now()
>>> d()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'datetime.datetime' object is not callable
>>>

If you want to compare only the date, you should call it thus:

return (self.pub_date.date() == datetime.date.today())


回答3:

"My question is: Why is datetime in my namespace without me using from datetime import *."

Because you did import datetime. Then you have datetime in your namespace. Not the CLASS datetime, but the MODULE.

Python does not treat import datetime the same way as from datetime import *. Stop asking why it does that, when it does not.

>>> import datetime
>>> date.today()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'date' is not defined
>>> 

There is something else happening. If it's Django magic or not, I don't know. I don't have a Django installation where I can try this at the moment. (If there is a super-quick way of making that happen, tell me. easy_installing Django wasn't enough. :) )