我想在静态范围内标记我的类函数的引用,即我想要类似的东西:
class MyClass:
func_mapping = {
'key_1': func_1, # Not accessible in this scope
'key_2': func_2
}
def func_1(self): # instance's functions
# Do something
def func_2(self):
# Do other things
如何映射我的功能?
基于用例的我想要的类结构如下:
class PlanTravel:
travel_mapping = {
'country_1': {
'precondtion': ['condition_1', 'condition_2'],
'planner': _travel_contry_1
},
'country_2': {
'precondtion': ['condition_1', 'condition_2'],
'planner': _travel_contry_2
}
}
def __init__(self, conditions, country):
self.conditions = conditions
self.country = country
def _verify_precondition(self):
preconditions = PlanTravel.travel_mapping[self.country]['precondtion']
for condition in preconditions:
if condition not in self.conditions:
raise Exception('You can not plan travel:', condition)
def travel(self):
self._verify_precondition()
travel_func = PlanTravel.travel_mapping[self.country]['planner']
travel_func()
def _travel_contry_1(self):
# Somthing
def _travel_contry_2(self):
# Somthing else
编辑如@vaultah所述,我首先可以定义函数,然后将它们映射到dict
,因为它们将在范围内可用。但我在课程开始时就想要它。如果有人想在将来浏览我的代码,那么他们可以在一开始就看到映射,他们知道要引用哪个函数。
答案 0 :(得分:1)
我目前可以想到的另一种方式是通过名称解析,如果你在lambda中添加它并在查找期间求助于额外的函数调用:
func_mapping = {
'key_1': lambda: MyClass.func_1,
'key_2': lambda: MyClass.func_2,
}
现在,必须使用以下方式进行不幸访问:
MyClass.func_mapping['key_1']()
另一个选项,将它包装在一个函数中,名称只在执行期间查找而不是编译:
def func_mapping(key):
func_mapping = {
'key_1': MyClass.func_1,
'key_2': MyClass.func_2,
}
return func_mapping[key]
这对眼睛来说有点好看,但你确实会把额外的功能当作负担。
答案 1 :(得分:1)
实现所需行为的直接方法是在类的func_mapping
方法中定义__init__
。当然,每次创建实例时都会重新定义,但那又如何呢?这只是一本小字典。
这是一个适用于Python 2和Python 3的演示。
class MyClass(object):
def __init__(self, mode):
func_mapping = {
'key_1': self.func_1,
'key_2': self.func_2,
}
self.func = func_mapping[mode]
def func_1(self):
return 'one'
def func_2(self):
return 'two'
a = MyClass('key_1')
print(a.func())
b = MyClass('key_2')
print(b.func())
<强>输出强>
one
two
答案 2 :(得分:1)
你的代码几乎可以工作,你只需要在映射之前定义方法,也不要通过类名引用它们,因为它还没有定义:
In [2]: class MyClass:
...: def func_1(self):
...: pass
...: def func_2(self):
...: pass
...: func_mapping = {
...: 'key_1': func_1,
...: 'key_2': func_2
...: }
...:
In [3]:
In [3]: MyClass.func_mapping
Out[3]:
{'key_1': <function __main__.MyClass.func_1>,
'key_2': <function __main__.MyClass.func_2>}
答案 3 :(得分:1)
另一种选择是将方法名称存储为字符串,然后使用getattr
。
class PlanTravel:
travel_mapping = {
'us': {
'precondtion': ['condition_1', 'condition_2']
'planner': '_us_planner'
}
# --cut--
def travel(self):
self._verify_precondition()
getattr(self,
PlanTravel.travel_mapping[self.country]['planner'])()
答案 4 :(得分:0)
在再次考虑这个问题时,我认为按照编码标准来实现它是不可能的。我解决这个问题的方法是:
class PlanTravel:
def __init__(self, conditions, country):
self.conditions = conditions
self.country = country
def _verify_precondition(self):
country_preconditions = {
'country_1': ['condition_1', 'condition_2'],
'country_2': ['condition_2', 'condition_2']
}
preconditions = country_preconditions[self.country]
for condition in preconditions:
if condition not in self.conditions:
raise Exception('You can not plan travel:', condition)
def travel(self):
self._verify_precondition()
travel_func = {
'country_1': self._travel_contry_1,
'country_2': self._travel_contry_2
}
travel_func[self.country]()
def _travel_contry_1(self):
# Somthing
def _travel_contry_2(self):
# Somthing else
然后我可以称之为:
plan_travel = PlanTravel('country_1')
plan_travel.travel()
这堂课看起来很干净。但消极的是,我将在两个地方进行国家制图。但是在第二个想法中,这些映射是在需要这些字段的块处完成的,这对我来说非常有意义。
随意批评我。任何建议/批评都是最受欢迎的:)