Κλήση λειτουργία της μονάδας, χρησιμοποιώντας το όνομά του (μια σειρά)

ψήφοι
1k

Ποιος είναι ο καλύτερος τρόπος να πάει για την κλήση μιας συνάρτησης δίνεται μια σειρά με το όνομα της συνάρτησης σε ένα πρόγραμμα Python. Για παράδειγμα, ας πούμε ότι έχω μια ενότητα foo, και έχω μια σειρά των οποίων το περιεχόμενο είναι bar. Ποιος είναι ο καλύτερος τρόπος να πάει για την κλήση foo.bar();

Θα πρέπει να πάρετε την τιμή επιστροφής της συνάρτησης, η οποία είναι ο λόγος που δεν χρησιμοποιούν μόνο eval. Έχω βρει τον τρόπο να το κάνουμε με τη χρήση evalγια να ορίσουμε μια συνάρτηση θερμοκρασία που επιστρέφει το αποτέλεσμα της εν λόγω κλήση της συνάρτησης, αλλά ελπίζω ότι υπάρχει ένας πιο κομψός τρόπος για να γίνει αυτό.

Δημοσιεύθηκε 06/08/2008 στις 04:36
πηγή χρήστη
Σε άλλες γλώσσες...                            


10 απαντήσεις

ψήφοι
1k

Υποθέτοντας μονάδα fooμε τη μέθοδο bar:

import foo
method_to_call = getattr(foo, 'bar')
result = method_to_call()

Όσον αφορά ότι πηγαίνει, γραμμές 2 και 3 μπορούν να συμπιεστούν σε:

result = getattr(foo, 'bar')()

αν αυτό έχει περισσότερο νόημα για την περίπτωση χρήσης σας. Μπορείτε να χρησιμοποιήσετε getattrμε αυτό τον τρόπο στην δεσμεύεται μεθόδους κατηγορίας παράδειγμα, οι μέθοδοι της μονάδας επιπέδου, οι μέθοδοι τάξη ... και ο κατάλογος συνεχίζεται.

Απαντήθηκε 06/08/2008 στις 04:57
πηγή χρήστη

ψήφοι
387
locals()["myfunction"]()

ή

globals()["myfunction"]()

ντόπιοι επιστρέφει ένα λεξικό με την τρέχουσα τοπική πίνακα συμβόλων. globals επιστρέφει ένα λεξικό με τις παγκόσμιες πίνακα συμβόλων.

Απαντήθηκε 07/05/2009 στις 13:45
πηγή χρήστη

ψήφοι
229

λύση Πατρικίου είναι ίσως η πιο καθαρή. Αν χρειαστεί να πάρει δυναμικά την ενότητα, καθώς, μπορείτε να εισαγάγετε αρέσει:

module = __import__('foo')
func = getattr(module, 'bar')
func()
Απαντήθηκε 07/08/2008 στις 12:35
πηγή χρήστη

ψήφοι
77

Απλά μια απλή συμβολή. Αν η τάξη που πρέπει να είναι παράδειγμα στο ίδιο αρχείο, μπορούμε να χρησιμοποιήσουμε κάτι σαν αυτό:

# Get class from globals and create an instance
m = globals()['our_class']()

# Get the function (from the instance) that we need to call
func = getattr(m, 'function_name')

# Call it
func()

Για παράδειγμα:

class A:
    def __init__(self):
        pass

    def sampleFunc(self, arg):
        print('you called sampleFunc({})'.format(arg))

m = globals()['A']()
func = getattr(m, 'sampleFunc')
func('sample arg')

# Sample, all on one line
getattr(globals()['A'](), 'sampleFunc')('sample arg')

Και, αν όχι μια κατηγορία:

def sampleFunc(arg):
    print('you called sampleFunc({})'.format(arg))

globals()['sampleFunc']('sample arg')
Απαντήθηκε 19/08/2012 στις 10:40
πηγή χρήστη

ψήφοι
64

Λαμβάνοντας υπόψη μια σειρά, με μια πλήρη διαδρομή python σε μια λειτουργία, αυτό είναι το πώς πήγα για να πάρει το αποτέλεσμα της εν λόγω λειτουργίας:

import importlib
function_string = 'mypackage.mymodule.myfunc'
mod_name, func_name = function_string.rsplit('.',1)
mod = importlib.import_module(mod_name)
func = getattr(mod, func_name)
result = func()
Απαντήθηκε 16/10/2013 στις 01:24
πηγή χρήστη

ψήφοι
30

Η απάντηση (ελπίζω) κανείς δεν ήθελε ποτέ

Eval όπως και τη συμπεριφορά

getattr(locals().get("foo") or globals().get("foo"), "bar")()

Γιατί να μην προσθέσετε αυτόματη εισαγωγή

getattr(
    locals().get("foo") or 
    globals().get("foo") or
    __import__("foo"), 
"bar")()

Σε περίπτωση που έχουμε επιπλέον λεξικά θέλουμε να ελέγξουμε

getattr(next((x for x in (f("foo") for f in 
                          [locals().get, globals().get, 
                           self.__dict__.get, __import__]) 
              if x)),
"bar")()

Πρέπει να πάμε βαθύτερα

getattr(next((x for x in (f("foo") for f in 
              ([locals().get, globals().get, self.__dict__.get] +
               [d.get for d in (list(dd.values()) for dd in 
                                [locals(),globals(),self.__dict__]
                                if isinstance(dd,dict))
                if isinstance(d,dict)] + 
               [__import__])) 
        if x)),
"bar")()
Απαντήθηκε 09/04/2014 στις 11:17
πηγή χρήστη

ψήφοι
26

Η καλύτερη απάντηση σύμφωνα με το προγραμματισμό FAQ Python θα είναι:

functions = {'myfoo': foo.bar}

mystring = 'myfoo'
if mystring in functions:
    functions[mystring]()

Το κύριο πλεονέκτημα αυτής της τεχνικής είναι ότι οι χορδές δεν χρειάζεται να ταιριάζουν με τα ονόματα των λειτουργιών. Αυτό είναι επίσης η κύρια τεχνική που χρησιμοποιείται για να μιμηθεί ένα κατασκεύασμα υπόθεση

Απαντήθηκε 24/10/2016 στις 13:20
πηγή χρήστη

ψήφοι
18

Για ό, τι αξίζει, αν χρειάζεται να περάσει τη λειτουργία (ή τάξη) το όνομα και το όνομα της εφαρμογής, όπως μια σειρά, τότε θα μπορούσατε να το κάνετε αυτό:

myFnName  = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn  = getattr(app,myFnName)
Απαντήθηκε 14/02/2012 στις 06:55
πηγή χρήστη

ψήφοι
15

Δοκιμάστε αυτό. Αν και αυτό εξακολουθεί να χρησιμοποιεί eval, το χρησιμοποιεί μόνο για να καλέσει τη λειτουργία από το τρέχον πλαίσιο . Στη συνέχεια, έχετε την πραγματική λειτουργία για να χρησιμοποιήσετε όπως εσείς επιθυμείτε.

Το κύριο όφελος για μένα από αυτό είναι ότι θα πάρετε οποιαδήποτε λάθη eval που σχετίζονται με το σημείο κλήτευση τη λειτουργία. Στη συνέχεια, θα πάρετε μόνο τα λάθη σχετιζόμενες με τη λειτουργία όταν καλείτε.

def say_hello(name):
    print 'Hello {}!'.format(name)

# get the function by name
method_name = 'say_hello'
method = eval(method_name)

# call it like a regular function later
args = ['friend']
kwargs = {}
method(*args, **kwargs)
Απαντήθηκε 07/12/2016 στις 18:29
πηγή χρήστη

ψήφοι
13

κανένας από ό, τι είχε προταθεί με βοήθησε. Έκανα ανακαλύψουν αυτό όμως.

<object>.__getattribute__(<string name>)(<params>)

Είμαι με τη χρήση python 2.66

Η ελπίδα αυτό βοηθά

Απαντήθηκε 28/12/2012 στις 17:56
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more