Вызов модулей из списка [dубликат]

Я пытаюсь использовать функциональное программирование для создания словаря, содержащего ключ и функцию для выполнения:

myDict={}
myItems=("P1","P2","P3",...."Pn")
def myMain(key):
    def ExecP1():
        pass
    def ExecP2():
        pass
    def ExecP3():
        pass
        ...
    def ExecPn():
        pass  

Теперь я видел код, используемый для определения определенных функций в модуле, и мне нужно сделать что-то вроде этого:

    for myitem in myItems:
        myDict[myitem] = ??? #to dynamically find the corresponding function

Итак, мой вопрос: как мне составить список всех функций Exec, а затем назначить их нужному элементу с помощью словаря? поэтому в конце у меня будет myDict["P1"]() #this will call ExecP1()

. Моя реальная проблема в том, что у меня есть тонны этих элементов, и я делаю библиотеку, которая будет обрабатывать их, поэтому конечному пользователю нужно только позвонить myMain("P1")

Я думаю, используя модуль проверки, но я не уверен, как это сделать.

Моя причина, чтобы избежать:

def ExecPn():
    pass
myDict["Pn"]=ExecPn

в том, что я должен защищать код, поскольку я использую его для обеспечения функции сценариев в моем приложении.

26
задан 19 April 2017 в 17:48

8 ответов

Это вызовет методы из словаря

Это вызовет методы из словаря

Создайте несколько модулей в соответствии с вашими требованиями. Если вы хотите передать аргументы, то передайте.

Создайте словарь, который будет вызывать эти модули согласно требованию.

    def function_1(arg):
        print("In function_1")

    def function_2(arg):
        print("In function_2")

    def function_3(fileName):
        print("In function_3")
        f_title,f_course1,f_course2 = fileName.split('_')
        return(f_title,f_course1,f_course2)


    def createDictionary():

        dict = {

            1 : function_1,
            2 : function_2,
            3 : function_3,

        }    
        return dict

    dictionary = createDictionary()
    dictionary[3](Argument)#pass any key value to call the method
0
ответ дан 15 August 2018 в 14:43

Упростите, упростите, упростите:

def p1(args):
    whatever

def p2(more args):
    whatever

myDict = {
    "P1": p1,
    "P2": p2,
    ...
    "Pn": pn
}

def myMain(name):
    myDict[name]()

Это все, что вам нужно.

Вы можете рассмотреть возможность использования dict.get с вызываемым по умолчанию, если name ссылается на недопустимую функцию -

def myMain(name):
    myDict.get(name, lambda: 'Invalid')()

(выбрал этот опрятный трюк у Martijn Pieters)

55
ответ дан 15 August 2018 в 14:43
  • 1
    Я знаю, это был мой первый выбор, но я хочу, чтобы конечный пользователь имел ограниченный доступ, поэтому пользователь не может изменить содержимое в словаре во время выполнения. – JohnnyDH 7 February 2012 в 04:41
  • 2
    Пользователь всегда может изменить все, что захочет, во время выполнения. Это Python. У них есть источник. – S.Lott 7 February 2012 в 04:41
  • 3
    Это зависит от пользователя. – JohnnyDH 7 February 2012 в 04:47
  • 4
    & quot; Это зависит от пользователя & quot ;? Что это значит? Не каждый пользователь может настроить код? Если это то, что вы имеете в виду, тогда вы должны потратить даже меньше времени , беспокоясь о «ограниченном доступе». Поскольку - эффективно - все пользователи могут настраивать код, вряд ли стоит пытаться добавить код для создания «ограниченного доступа». Идите для простых во всех случаях. – S.Lott 7 February 2012 в 05:05
  • 5
    @JohnnyDH Это сумасшедший аргумент. Если у вас есть реальное требование сделать код более «безопасным», то вы должны использовать скомпилированный язык - python не является подходящим инструментом для работы, и ваша ответственность заключается в том, чтобы объяснить это клиенту. Добавление строк дерьма к вашему коду, чтобы попробовать и обходная внутренняя открытость python не является мерой безопасности - это невозможно сделать должным образом, и попытка сделать это сделает ваш код более уродливым и хрупким – wim 7 February 2012 в 06:33

Упростить, упростить, упростить + DRY:

tasks = {}
task = lambda f: tasks.setdefault(f.__name__, f)

@task
def p1():
    whatever

@task
def p2():
    whatever

def my_main(key):
    tasks[key]()
16
ответ дан 15 August 2018 в 14:43

Вы можете просто использовать

myDict = {
    "P1": (lambda x: function1()),
    "P2": (lambda x: function2()),
    ...,
    "Pn": (lambda x: functionn())}
myItems = ["P1", "P2", ..., "Pn"]

for item in myItems:
    myDict[item]()
0
ответ дан 15 August 2018 в 14:43

Вы зря теряете время:

Вы собираетесь написать много бесполезного кода и ввести новые ошибки. Чтобы выполнить функцию, ваш пользователь должен знать имя P1 в любом случае. И т. Д. И т. Д. И т. Д.

Просто поместите все свои функции в файл .py:

# my_module.py

def f1():
    pass

def f2():
    pass

def f3():
    pass

И используйте их следующим образом:

import my_module

my_module.f1()
my_module.f2()
my_module.f3()

или:

from my_module import f1
from my_module import f2
from my_module import f3

f1()
f2()
f3()

Этого должно быть достаточно для стартеров.

0
ответ дан 15 August 2018 в 14:43
  • 1
    Вы правы, что конечный пользователь будет знать имя, и я очень ценю ваш совет, я стартер, но только на питоне, я очень хорошо знаю некоторые принципы программирования, но я не реализую это в личном проекте, это связано с работой и клиент просит надежное приложение, и правда в том, что это программное обеспечение будет использоваться кучей обезьян, и они хотят видеть все, кроме простого и простого приложения ... – JohnnyDH 7 February 2012 в 05:00
  • 2
    @JohnnyDH, опишите, по крайней мере, несколько разных сценариев, когда эти обезьяны захватывают ваше приложение. Это может дать вам несколько ответов, более подходящих для вашей ситуации. – Misha Akovantsev 7 February 2012 в 05:07
  • 3
    Приложение представляет собой интерфейс GUI для устройства, мы предлагаем «скриптинг», функции в нашем приложении, но мы не предлагаем «полный». поддержка python, поскольку это наша главная цель, ограничить доступ. Конечными пользователями являются продавцы, люди, которым нужно только следовать руководству для написания основных «скриптов», они не приняли собственный «язык», они хотели использовать на основе python, поэтому да, пользователь может изменить словарь в одна багги-линия и продукт не будут работать, поэтому да, им просто нужно перезапустить, но клиент будет жаловаться. – JohnnyDH 7 February 2012 в 05:34
  • 4
    @JonnyDH Ваши аргументы на самом деле не имеют смысла. «С одной баггиной линией» они могут скрыть вашу основную функцию так же легко, как они могут изменить словарь. По правде говоря, вряд ли это произойдет, потому что ни одна из них не похожа на законную нормальную операцию. Но этот ответ предполагает, что вы даже не используете словарь, вы просто даете им один открытый модуль, который только содержит то, что должен вызвать конечный пользователь. Существует ничего , если вы беспокоитесь о том, что они импортируют другие модули и возится со своими внутренностями. – Ben 7 February 2012 в 07:21
  • 5
    @Ben Поверьте мне, я очень этому понимаю, у меня есть 8 лет, предлагающих программные решения, это первый раз, когда я использую Python, и я хотел бы использовать многие функции безопасности с других языков, однако я не могу контролировать его, мне нужно чтобы сделать модуль «только для чтения», заказчик просит нас дать им «доказательства», что функция сценариев максимально безопасна, мы предложили проприетарный язык, поэтому у нас был полный контроль над процессом создания скриптов, но они отказались, и мы не можем контролировать все без ущерба для гибкости для этой функции. – JohnnyDH 8 February 2012 в 01:59
def p1( ):
    print("in p1")

def p2():
    print("in p2")

myDict={
    "P1": p1,
    "P2": p2

}

name=input("enter P1 or P2")

myDictname

-1
ответ дан 15 August 2018 в 14:43
[F1]
1
ответ дан 15 August 2018 в 14:43
  • 1
    Я знаю, что это легко сделать, я действительно это делаю, но тогда у моего словаря нет защиты, мне действительно нужно запретить конечному пользователю модифицировать этот словарь – JohnnyDH 7 February 2012 в 04:43
  • 2
    Затем создайте класс, защищенный (и я использую этот термин свободно) для создания декораций для записи только для записи и использую __ префиксные переменные в (давайте честно, тщетно пытаемся) скрыть детали реализации от пользователя. Взгляните на combatquaker.com/pyanno для некоторого вдохновения .. – synthesizerpatel 7 February 2012 в 04:49
[F1]
2
ответ дан 15 August 2018 в 14:43

Другие вопросы по тегам:

Похожие вопросы: