如何__getattr__在模块上实现类的等价?
当调用模块静态定义的属性中不存在的函数时,我希望在该模块中创建一个类的实例,并在模块上的属性查找中使用与失败相同的名称调用其上的方法.
class A(object):
def salutation(self, accusative):
print "hello", accusative
# note this function is intentionally on the module, and not the class above
def __getattr__(mod, name):
return getattr(A(), name)
if __name__ == "__main__":
# i hope here to have my __getattr__ function above invoked, since
# salutation does not exist in the current namespace
salutation("world")
Run Code Online (Sandbox Code Playgroud)
这使:
matt@stanley:~/Desktop$ python getattrmod.py
Traceback (most recent call last):
File "getattrmod.py", line 9, in <module>
salutation("world")
NameError: name 'salutation' is not …Run Code Online (Sandbox Code Playgroud) 可能重复:
如何在Python中执行变量变量?
我有一个变量,并为其分配了一个字符串,我想根据该字符串定义一个新变量.
foo = "bar"
foo = "something else"
# What I actually want is:
bar = "something else"
Run Code Online (Sandbox Code Playgroud) 编辑:
请参阅本问题底部的完整答案.
tl;博士回答:Python有静态嵌套的范围.的静态 方面可以与隐变量声明相互作用,产生非显而易见的结果.
(这可能特别令人惊讶,因为语言通常具有动态性质).
我认为我对Python的范围规则有一个很好的处理,但是这个问题让我彻底陷入困境,而且我的google-fu让我失望了(不是我很惊讶 - 看看问题标题;)
我将从一些可以按预期工作的示例开始,但是可以自由地跳到示例4的多汁部分.
例1.
>>> x = 3
>>> class MyClass(object):
... x = x
...
>>> MyClass.x
3
Run Code Online (Sandbox Code Playgroud)
足够简单:在类定义期间,我们能够访问外部(在本例中为全局)范围中定义的变量.
例2.
>>> def mymethod(self):
... return self.x
...
>>> x = 3
>>> class MyClass(object):
... x = x
... mymethod = mymethod
...
>>> MyClass().mymethod()
3
Run Code Online (Sandbox Code Playgroud)
再次(忽略了为什么人们可能想要这样做),这里没有任何意外:我们可以访问外部范围中的函数.
注意:正如Frédéric在下面指出的那样,这个功能似乎不起作用.请参见示例5(及更高版本).
例3.
>>> def myfunc():
... x = 3
... class MyClass(object):
... x = x
... return MyClass
... …Run Code Online (Sandbox Code Playgroud) 我试图从类中的方法动态创建模块级函数.因此,对于类中的每个方法,我想创建一个具有相同名称的函数,该函数创建类的实例,然后调用该方法.
我想这样做的原因是我可以采用面向对象的方法来创建Fabric文件.由于Fabric将调用模块级函数而不是类的方法,因此这是我的解决方法.
我使用以下链接让我开始
我提出了以下代码
import inspect
import sys
import types
class TestClass(object):
def __init__(self):
pass
def method1(self, arg1):
print 'method 1 %s' % arg1
def method2(self):
print 'method 2'
def fabric_class_to_function_magic(module_name):
# get the module as an object
print module_name
module_obj = sys.modules[module_name]
print dir(module_obj)
# Iterate over the methods of the class and dynamically create a function
# for each method that calls the method and add it to the current module
for …Run Code Online (Sandbox Code Playgroud) 我想从脚本安装和导入一个包。然后我想在那个脚本中添加from x import y和from x import *。(我实际上是在做一些功能)。
我使用subprocessand成功安装和导入importlib。但我在from x import y和 中不知所措from x import *。尝试了这些代码和其他一些代码。
globals()[package] = importlib.import_module('package','class')
globals()[package] = importlib.import_module('class','package')
globals()[package] = importlib.import_module('package','*')
globals()[package] = importlib.import_module('*','package')
importlib.import_module('gtts','gTTS')
importlib.import_module('gtts','*')
Run Code Online (Sandbox Code Playgroud)
但他们没有工作。节目:
NameError: name 'gTTS' is not defined
ModuleNotFoundError: No module named 'gTTS'
Run Code Online (Sandbox Code Playgroud)
等等。
我想编写一个可以在 Linux 和 Solaris 上执行的脚本。大多数逻辑在两个操作系统上都是相同的,因此我只编写了一个脚本。但是因为一些部署的结构会有所不同(文件位置、文件格式、命令语法),所以两个平台上的一些功能会有所不同。
这可以像这样处理
if 'linux' in sys.platform:
result = do_stuff_linux()
if 'sun' in sys.platform:
result = do_stuff_solaris()
more_stuf(result)
...
Run Code Online (Sandbox Code Playgroud)
然而,ifs在整个代码中散布这些似乎既麻烦又不优雅。我也可以在某些中注册函数dict,然后通过 dict 调用函数。大概好看一点。
关于如何做到这一点的任何更好的想法?
python ×6
python-3.x ×2
fabric ×1
getattr ×1
module ×1
namespaces ×1
package ×1
pip ×1
scope ×1