首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过internet/多个协议导入python模块或动态创建模块

通过internet/多个协议导入python模块或动态创建模块
EN

Stack Overflow用户
提问于 2013-09-11 16:55:22
回答 4查看 6.8K关注 0票数 11

是否可以使用import (https),ftpsmb或其他协议从互联网上获取Python模块?如果是这样的话,是怎么做的?如果没有,为什么?

我想这是为了让Python使用更多的一个协议(读取文件系统),并使它也能够使用其他协议。是的,我同意它会慢很多倍,但一些优化和更大的未来带宽肯定会平衡它。

等:

代码语言:javascript
复制
import site

site.addsitedir("https://bitbucket.org/zzzeek/sqlalchemy/src/e8167548429b9d4937caaa09740ffe9bdab1ef61/lib")

import sqlalchemy
import sqlalchemy.engine
EN

回答 4

Stack Overflow用户

发布于 2015-12-28 10:01:30

另一个版本,

我喜欢的答案。当应用它时,我将它简化了一些--类似于javascript包含在HTTP上的外观。

其结果是:

代码语言:javascript
复制
import os
import imp
import requests

def import_cdn(uri, name=None):
    if not name:
        name = os.path.basename(uri).lower().rstrip('.py')

    r = requests.get(uri)
    r.raise_for_status()

    codeobj = compile(r.content, uri, 'exec')
    module = imp.new_module(name)
    exec (codeobj, module.__dict__)
    return module

使用:

代码语言:javascript
复制
redisdl = import_cdn("https://raw.githubusercontent.com/p/redis-dump-load/master/redisdl.py")

# Regular usage of the dynamic included library
json_text = redisdl.dumps(host='127.0.0.1')
  • Tip -将import_cdn函数放在一个公共库中,这样您就可以重用这个小函数了。
  • 请记住,当在http上没有连接到该文件的时,将失败。
票数 5
EN

Stack Overflow用户

发布于 2013-09-11 19:20:06

原则上,是的,但是所有内置的工具--在某种程度上支持这一点--都要经过文件系统。

要做到这一点,您必须从哪里加载源代码,用compile编译它,并用新模块的__dict__编译它。见下文。

我已经将实际从互联网上获取的文本和解析uris等作为读者的练习(对于初学者:我建议使用requests)。

佩普302术语中,这将是loader.load_module函数背后的实现(参数不同)。有关如何将其与import语句集成的详细信息,请参阅该文档。

代码语言:javascript
复制
import imp
modulesource = 'a=1;b=2' #load from internet or wherever
def makemodule(modulesource,sourcestr='http://some/url/or/whatever',modname=None):
    #if loading from the internet, you'd probably want to parse the uri, 
    # and use the last part as the modulename. It'll come up in tracebacks
    # and the like.
    if not modname: modname = 'newmodulename'
    #must be exec mode
    # every module needs a source to be identified, can be any value
    # but if loading from the internet, you'd use the URI
    codeobj = compile(modulesource, sourcestr, 'exec')
    newmodule = imp.new_module(modname)
    exec(codeobj,newmodule.__dict__)
    return newmodule
newmodule = makemodule(modulesource)
print(newmodule.a)

此时,newmodule在作用域上已经是一个模块对象,因此您不需要导入它或任何东西。

代码语言:javascript
复制
modulesource = '''
a = 'foo'
def myfun(astr):
    return a + astr
'''
newmod = makemodule(modulesource)
print(newmod.myfun('bat'))

Ideone这里:http://ideone.com/dXGziO

使用python 2进行测试,应该使用python 3(使用文本兼容的打印;使用类似函数的exec语法)。

票数 4
EN

Stack Overflow用户

发布于 2013-09-11 19:57:09

这似乎是自写导入钩子的用例。在佩普302中查找它们到底是如何工作的。

本质上,您必须提供一个finder对象,而finder对象又提供一个加载器对象。乍一看,我并不理解这个过程(否则我会更加明确),但是PEP包含了实现这些东西所需的所有细节。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18747043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档