我遇到的代码如下:
import redis
import redis as originalRedis
OriginalRedis = originalRedis.Redis # note the uppercase O
class Redis(redis.Redis):
def keys(self, pattern='*'):
# custom implementation to be done here
client = OriginalRedis(self.host, port=self.port, db=self.db)
return client.keys(pattern)
def flushKeys(self):
# some custom implementation TBD here too
return True
redis.Redis = Redis
现在我的问题是关于进口声明的。当我们导入类似的东西时,我们两个引用相同的模块吗? Aren的模块导入应该是单例对象吗?我已经尝试了以下
import datetime
import datetime as dt
dt is datetime
True
所以我猜测单个模块有一个参考,因为id(dt)
和id(datetime)
是相同的。任何人都可以详细说明为什么以这种方式使用它?提前谢谢!
答案 0 :(得分:3)
当我们导入类似的内容时,我们会引用同一个模块吗?
正确。所有as
子句都将新名称绑定到对象。如果直接导入模块,然后通过as
导入同一模块但名称不同,则两个名称都将指向完全相同的对象。例如:
>>> import re
>>> import re as regex
>>>
>>> id(re) == id(regex)
True
>>>
documentation for import
statements also mentions this behavior:
如果模块名称后跟as,则后面的名称将直接绑定到导入的模块。
模块导入不应该是单例对象吗?
是的,你可以这样想。 Python只根据需要执行导入模块的代码,因此技术上是肯定的。模块对象是单例。但你必须记住,即使是单身人士也可以拥有多个名字。
仅仅因为您为对象创建了一个新别名,并不意味着您创建了一个全新的对象。您所做的只是创建一个新名称来引用完全相同的对象。如果不是这样,那么上面的代码将返回False
为re
而regex
将是不同的对象,
答案 1 :(得分:0)
我认为OP在实例和引用之间混淆了!
当我们导入类似的内容时,我们有两个对同一模块的引用吗?
import datetime
import datetime as dt
是。但是你也应该知道对象/实例与引用不同(显然你现在已经知道了!)。我认为OP认为多次导入将del
先前对模块的引用(因此使先前的导入过时)并创建一个新的,但事实并非如此!请亲自查看下面的代码,并确保这一点。
import datetime # first import
import datetime as dt # second import with an alias
id(dt)
X # X stands for some random address
id(datetime)
X # same address as previous
import datetime # here OP thinks it'll exhaust the previous instance
id(datetime)
X # to OP's surprise it remains the same!
模块导入不应该是单例对象吗?
是。并且没有语言禁止您为相同的单例对象创建任意数量的引用!
注意:有些OP只是像我一样的人,甚至是我!
谢谢大家!