我不知道该怎么称呼它,但我已经在TCL和Elixir中完成了。当您替换变量以使代码更简单时。这是解释它的可怕方式。这个例子会说清楚:
这是常规代码:
def get(self, item):
if item == 'name':
return self.name
elif item == 'age':
return self.age
我想把它变成这样的东西:
def get(self, item):
return self.%{item}
它将变量item
中的值解释为变量的名称。就像我说的,我在其他语言中做过这样的事情,但我不知道它叫什么,我不知道如何在python中做到这一点。
PS。这是TCL的一个简单例子
c:\repos\flow>tclsh
% set foo bar
bar
% set bar baz
baz
% puts $foo
bar
% puts [set $foo]
baz
了解[set $foo]
基本上如何告诉解释器将$foo
的值解释为变量名称{变形bar
,然后命令puts
占用bar
baz
}作为变量并打印出其值{字符串% set a puts
puts
% $a hello\ world
hello world
你甚至可以用Tcl中的命令来做这种事情
# Load the data
fin = open("b.txt", 'r')
translist = []
for line in fin:
trans = line.strip().split(' ')
translist.append(trans)
答案 0 :(得分:4)
您可以使用getattr
:
def get(self, item):
return getattr(self, item)
getattr
也可以像getattr(object, attrname)
一样使用,并且行为方式相同。
但是,必须这样做通常是不好的做法。您可能应该使用字典。 字典的例子:
def __init__(self, whatever):
self.stuff = {"name": "bob", "age": 40}
def get(self, item):
return self.stuff[item]
另请参阅:this
如果要从全局或本地范围获取变量,可以使用:
a = 1
def f():
b = 2
print(globals()["a"])
#print(globals()["b"]) fails, b is not global
print(locals["b"]) # works, b is in the local scope
还有一种非常普遍的方式(也非常丑陋和不安全):
foo="bar"
bar="baz"
baz = ""
obj=None
eval(f"obj.{foo}") # obj.bar
eval(f"obj.{eval(f'{foo}')}") # obj.baz
eval(f"{foo}") # bar / "baz"
eval(f"{eval(f'{foo}')}") # baz / ""
请永远不要使用它。
答案 1 :(得分:1)
您可以尝试这种方法:
class foo():
cls_attr = "hello"
def __init__(self):
self.name = "i am foo"
self.age = 0
self.gender = None
self.bar = "this is bar"
def get(self, item):
if item in foo.__dict__:
return foo.__dict__[item]
elif item in self.__dict__:
return self.__dict__[item]
else:
return None
>>> f = foo()
>>> f.get('gender')
>>> f.get('bar')
'this is bar'
>>> f.get('name')
'i am foo'
>>> f.get('nothing')
>>> f.get('age')
0
>>> f.get('cls_attr')
'hello'
根据internet_user的评论更新了我的回答。现在它应该返回实例和类属性。
编辑:好的我不知道怎么做超类属性(我的意思是我可能猜它是super().__dict__
),但是在一天结束时,internet_user的答案是一个更好的版本。我将在这里留下这个答案,让未来的观众看到效率低下的比较方法。