Не используйте exec
или eval
. Вместо этого используйте getattr
.
Также обратите внимание, что set_age
является одновременно методом и атрибутом, постарайтесь избежать этого.
import re
class PersonalDetails:
def __init__(self, personal_details):
self.personal_details = personal_details
def set_gender(self):
self.gender = 'Male'
def set_age(self):
self.age = 22
def execute_all_settings(self):
'''
wrapper for setting all variables that start with set.
Will skip anything not matching regex '^set'
'''
to_execute = [i for i in dir(self) if re.search('^set', i)]
print(to_execute)
for func_name in to_execute:
getattr(self, func_name)()
pd = PersonalDetails('')
pd.execute_all_settings()
print(pd.gender)
# ['set_age', 'set_gender']
# Male
Это решение будет работать до тех пор, пока все методы «set» либо не ожидают никаких аргументов (что является текущим вариантом использования), либо все они ожидают одинаковых аргументов.
Смотрите на WPF CommandParameter Обязательная проблема. Возможно, это может обеспечить некоторые указатели относительно того, что продолжается.
Проблема состоит в том, что ContextMenu в корне его собственного визуального дерева, таким образом, любой RelativeSource. Привязка FindAncestor не пойдет мимо ContextMenu.
Одно решение состоит в том, чтобы использовать свойство PlacementTarget для установки двухэтапной привязки от Маркировки:
<Label Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={
x:Type TreeView}}}">
<Label.ContextMenu>
<ContextMenu>
<MenuItem Header="Delete" Command="{x:Static local:Commands.DeleteCommand}"
CommandParameter="{Binding PlacementTarget.Tag, RelativeSource={
RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"/>
</ContextMenu>
</Label.ContextMenu>
</Label>
Это вполне hacky, как бы то ни было. Вы - более обеспеченная установка свойства CommandTarget Вашего MenuItem к PlacementTarget ContextMenu и наличию обработчика команд на Вашем TreeView. Это означает, что Вы не должны будете раздавать TreeView.