Τι σημαίνει ** (διπλό αστέρι / αστερίσκο) και * (αστέρι / αστερίσκο) κάνει για τις παραμέτρους;

ψήφοι
1k

Στους ακόλουθους ορισμούς μέθοδο, τι το *και **κάνει για param2;

def foo(param1, *param2):
def bar(param1, **param2):
Δημοσιεύθηκε 31/08/2008 στις 16:04
πηγή χρήστη
Σε άλλες γλώσσες...                            


22 απαντήσεις

ψήφοι
10

Από την τεκμηρίωση Python:

Εάν υπάρχουν περισσότερες θέσεις επιχειρήματα ό, τι υπάρχουν τυπικές υποδοχές παράμετρο, μια εξαίρεση TypeError αυξάνεται, εκτός και αν μια τυπική παράμετρο χρησιμοποιώντας τη σύνταξη «* αναγνωριστικό» υπάρχει? στην περίπτωση αυτή, ότι η τυπική παράμετρος λαμβάνει μια πλειάδα που περιέχει την περίσσεια θέσης επιχειρήματα (ή μια κενή πλειάδα αν δεν υπήρχαν περίσσεια θέσεως επιχειρήματα).

Εάν κάποιο επιχείρημα λέξη-κλειδί που δεν αντιστοιχεί σε ένα επίσημο όνομα παραμέτρου, μια εξαίρεση TypeError αυξάνεται, εκτός και αν μια τυπική παράμετρο χρησιμοποιώντας τη σύνταξη «** αναγνωριστικό» υπάρχει? στην περίπτωση αυτή, ότι η τυπική παράμετρος λαμβάνει ένα λεξικό που περιέχει τα περίσσεια επιχειρήματα λέξη-κλειδί (χρησιμοποιώντας τις λέξεις-κλειδιά όπως κλειδιά και τις αξίες επιχείρημα αντίστοιχες τιμές), ή ένα (νέο) άδειο λεξικό αν δεν υπήρχαν περίσσεια επιχειρήματα λέξη-κλειδί.

Απαντήθηκε 31/08/2008 στις 16:07
πηγή χρήστη

ψήφοι
1k

Ο *argsκαι **kwargsείναι ένα κοινό ιδίωμα για να επιτρέψει αυθαίρετη σειρά επιχειρημάτων για να λειτουργεί όπως περιγράφεται στην ενότητα περισσότερες πληροφορίες σχετικά με τον καθορισμό λειτουργίες στην τεκμηρίωση Python.

Η *argsθα σας δώσει όλες τις παραμέτρους λειτουργίας και μια πλειάδα :

In [1]: def foo(*args):
   ...:     for a in args:
   ...:         print a
   ...:         
   ...:         

In [2]: foo(1)
1


In [4]: foo(1,2,3)
1
2
3

Η **kwargsθα σας δώσει όλες επιχειρήματα λέξη-κλειδί , εκτός από εκείνες που αντιστοιχούν σε μια τυπική παράμετρο ως ένα λεξικό.

In [5]: def bar(**kwargs):
   ...:     for a in kwargs:
   ...:         print a, kwargs[a]
   ...:         
   ...:         

In [6]: bar(name='one', age=27)
age 27
name one

Και τα δύο ιδιώματα μπορεί να αναμιχθεί με την κανονική επιχειρήματα για να επιτρέψει ένα σύνολο σταθερών και κάποια μεταβλητή επιχειρήματα:

def foo(kind, *args, **kwargs):
   pass

Μια άλλη χρήση του *lιδίωμα είναι να αποσυμπιέσετε λίστες επιχείρημα όταν καλείτε μια λειτουργία.

In [9]: def foo(bar, lee):
   ...:     print bar, lee
   ...:     
   ...:     

In [10]: l = [1,2]

In [11]: foo(*l)
1 2

Στην Python 3 είναι δυνατόν να χρησιμοποιηθούν *lστην αριστερή πλευρά της εκχώρησης ( Extended Iterable Αποσυσκευασία ), αν και δίνει μια λίστα αντί για μια πλειάδα Στο πλαίσιο αυτό:

first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]

Επίσης Python 3 προσθέτει νέα σημασιολογική (ανατρέξτε PEP 3102 ):

def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
    pass

Η λειτουργία αυτή δέχεται μόνο 3 θέσεις επιχειρήματα, και πάντα μετά *μπορεί να περάσει μόνο ως επιχειρήματα λέξη-κλειδί.

Απαντήθηκε 31/08/2008 στις 16:17
πηγή χρήστη

ψήφοι
123

Το ενιαίο * σημαίνει ότι δεν μπορεί να υπάρξει οποιοσδήποτε αριθμός επιπλέον θέσης επιχειρήματα. foo()μπορεί να γίνει επίκληση όπως foo(1,2,3,4,5). Στο σώμα του foo () param2 είναι μία αλληλουχία που περιέχει 2-5.

Το διπλό ** σημαίνει ότι δεν μπορεί να υπάρξει οποιοσδήποτε αριθμός επιπλέον το όνομα παραμέτρους. bar()μπορεί να γίνει επίκληση όπως bar(1, a=2, b=3). Στο σώμα της ράβδου () param2 είναι ένα λεξικό που περιέχει { 'a': 2, 'b': 3}

Με τον παρακάτω κωδικό:

def foo(param1, *param2):
    print param1
    print param2

def bar(param1, **param2):
    print param1
    print param2

foo(1,2,3,4,5)
bar(1,a=2,b=3)

η έξοδος είναι

1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}
Απαντήθηκε 31/08/2008 στις 16:20
πηγή χρήστη

ψήφοι
428

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

def foo(x,y,z):
    print("x=" + str(x))
    print("y=" + str(y))
    print("z=" + str(z))

Μπορείτε να κάνετε πράγματα όπως:

>>> mylist = [1,2,3]
>>> foo(*mylist)
x=1
y=2
z=3

>>> mydict = {'x':1,'y':2,'z':3}
>>> foo(**mydict)
x=1
y=2
z=3

>>> mytuple = (1, 2, 3)
>>> foo(*mytuple)
x=1
y=2
z=3

Σημείωση: Τα πλήκτρα mydictπρέπει να ονομαστεί ακριβώς όπως τις παραμέτρους της λειτουργίας foo. Διαφορετικά, θα ρίξει ένα TypeError:

>>> mydict = {'x':1,'y':2,'z':3,'badnews':9}
>>> foo(**mydict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() got an unexpected keyword argument 'badnews'
Απαντήθηκε 31/08/2008 στις 16:47
πηγή χρήστη

ψήφοι
20

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

Απαντήθηκε 11/09/2012 στις 05:33
πηγή χρήστη

ψήφοι
102

Τι κάνει **(διπλό άστρο) και *(αστέρι) κάνει για τις παραμέτρους

Επιτρέπουν για τις λειτουργίες που θα οριστεί να αποδέχεται και για τους χρήστες για να περάσει οποιοδήποτε αριθμό των επιχειρημάτων, θέσης ( *) και λέξεων-κλειδιών ( **).

Καθορισμός Λειτουργίες

*argsεπιτρέπει για οποιοδήποτε αριθμό των προαιρετικών ορίσματα σε συγκεκριμένες θέσεις (παραμέτρους), η οποία θα ανατεθεί σε μια πλειάδα ονομάζεται args.

**kwargsεπιτρέπει για οποιοδήποτε αριθμό των προαιρετικών επιχειρήματα λέξη-κλειδί (παράμετροι), η οποία θα είναι σε dict το όνομα kwargs.

Μπορείτε να (και πρέπει) να επιλέξετε οποιοδήποτε κατάλληλο όνομα, αλλά αν η πρόθεση είναι για τα επιχειρήματα να μη ειδικής σημασιολογία, argsκαι kwargsείναι τυπικά ονόματα.

Επέκταση, Περνώντας οποιοδήποτε αριθμό των επιχειρημάτων

Μπορείτε επίσης να χρησιμοποιήσετε *argsκαι **kwargsνα περάσει σε παραμέτρους από τις λίστες (ή οποιαδήποτε iterable) και DICTS (ή οποιαδήποτε χαρτογράφηση), αντίστοιχα.

Η λειτουργία recieving τις παραμέτρους δεν πρέπει να γνωρίζουν ότι επεκτείνεται.

Για παράδειγμα, xrange Python 2 του δεν αναμένει ρητά *args, αλλά δεδομένου ότι χρειάζονται 3 ακέραιοι ως επιχειρήματα:

>>> x = xrange(3) # create our *args - an iterable of 3 integers
>>> xrange(*x)    # expand here
xrange(0, 2, 2)

Ως ένα άλλο παράδειγμα, μπορούμε να χρησιμοποιήσουμε dict επέκταση str.format:

>>> foo = 'FOO'
>>> bar = 'BAR'
>>> 'this is foo, {foo} and bar, {bar}'.format(**locals())
'this is foo, FOO and bar, BAR'

Νέα σε Python 3: Καθορισμός λειτουργεί με λέξη-κλειδί μόνο επιχειρήματα

Μπορείτε να έχετε λέξη-κλειδί μόνο επιχειρήματα μετά την *args- για παράδειγμα, εδώ, kwarg2πρέπει να δοθεί ως επιχείρημα λέξη-κλειδί - όχι κατά θέση:

def foo(arg, kwarg=None, *args, kwarg2=None, **kwargs): 
    return arg, kwarg, args, kwarg2, kwargs

Χρήση:

>>> foo(1,2,3,4,5,kwarg2='kwarg2', bar='bar', baz='baz')
(1, 2, (3, 4, 5), 'kwarg2', {'bar': 'bar', 'baz': 'baz'})

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

def foo(arg, kwarg=None, *, kwarg2=None, **kwargs): 
    return arg, kwarg, kwarg2, kwargs

Εδώ, kwarg2και πάλι πρέπει να είναι σαφώς το όνομα, το επιχείρημα λέξη-κλειδί:

>>> foo(1,2,kwarg2='kwarg2', foo='foo', bar='bar')
(1, 2, 'kwarg2', {'foo': 'foo', 'bar': 'bar'})

Και δεν μπορούμε πλέον να αποδέχεται απεριόριστη θέσης επιχειρήματα γιατί δεν έχουμε *args*:

>>> foo(1,2,3,4,5, kwarg2='kwarg2', foo='foo', bar='bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() takes from 1 to 2 positional arguments 
    but 5 positional arguments (and 1 keyword-only argument) were given

Και πάλι, πιο απλά, εδώ χρειαζόμαστε kwargνα δοθεί με βάση το όνομα, όχι κατά θέση:

def bar(*, kwarg=None): 
    return kwarg

Σε αυτό το παράδειγμα, βλέπουμε ότι αν προσπαθήσουμε να περάσει kwargθέσεις, έχουμε ένα σφάλμα:

>>> bar('kwarg')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bar() takes 0 positional arguments but 1 was given

Θα πρέπει να περάσει ρητά την kwargπαράμετρο ως επιχείρημα λέξη-κλειδί.

>>> bar(kwarg='kwarg')
'kwarg'

Python 2 συμβατό demos

*args(συνήθως είπε ότι «αστέρι-args») και **kwargs(αστέρια μπορεί να υπονοείται λέγοντας «kwargs», αλλά είναι ρητή με «kwargs διπλό άστρο») είναι κοινά ιδιώματα της Python για τη χρήση του *και **συμβολισμό. Αυτά τα ειδικά ονόματα των μεταβλητών δεν απαιτούνται (π.χ. μπορείτε να χρησιμοποιήσετε *foosκαι **bars), αλλά η αποχώρηση από το συνεδριακό είναι πιθανό να εξοργίσουν τους συναδέλφους προγραμματιστές Python σας.

Εμείς συνήθως χρησιμοποιούν αυτά, όταν δεν ξέρουμε ποια είναι η λειτουργία μας πρόκειται να λάβει ή πόσα επιχειρήματα που μπορούν να περνά, και μερικές φορές ακόμα και κατά την ονομασία κάθε μεταβλητή ξεχωριστά θα πάρει πολύ βρώμικο και περιττή (αλλά αυτό είναι μια περίπτωση όπου συνήθως ρητή είναι καλύτερα από ό, σιωπηρή).

παράδειγμα 1

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

def foo(a, b=10, *args, **kwargs):
    '''
    this function takes required argument a, not required keyword argument b
    and any number of unknown positional arguments and keyword arguments after
    '''
    print('a is a required argument, and its value is {0}'.format(a))
    print('b not required, its default value is 10, actual value: {0}'.format(b))
    # we can inspect the unknown arguments we were passed:
    #  - args:
    print('args is of type {0} and length {1}'.format(type(args), len(args)))
    for arg in args:
        print('unknown arg: {0}'.format(arg))
    #  - kwargs:
    print('kwargs is of type {0} and length {1}'.format(type(kwargs),
                                                        len(kwargs)))
    for kw, arg in kwargs.items():
        print('unknown kwarg - kw: {0}, arg: {1}'.format(kw, arg))
    # But we don't have to know anything about them 
    # to pass them to other functions.
    print('Args or kwargs can be passed without knowing what they are.')
    # max can take two or more positional args: max(a, b, c...)
    print('e.g. max(a, b, *args) \n{0}'.format(
      max(a, b, *args))) 
    kweg = 'dict({0})'.format( # named args same as unknown kwargs
      ', '.join('{k}={v}'.format(k=k, v=v) 
                             for k, v in sorted(kwargs.items())))
    print('e.g. dict(**kwargs) (same as {kweg}) returns: \n{0}'.format(
      dict(**kwargs), kweg=kweg))

Μπορούμε να ελέγξετε την ηλεκτρονική βοήθεια για την υπογραφή της συνάρτησης, με help(foo)το οποίο μας λέει

foo(a, b=10, *args, **kwargs)

Ας το ονομάσουμε αυτή τη λειτουργία με foo(1, 2, 3, 4, e=5, f=6, g=7)

που εκτυπώνει:

a is a required argument, and its value is 1
b not required, its default value is 10, actual value: 2
args is of type <type 'tuple'> and length 2
unknown arg: 3
unknown arg: 4
kwargs is of type <type 'dict'> and length 3
unknown kwarg - kw: e, arg: 5
unknown kwarg - kw: g, arg: 7
unknown kwarg - kw: f, arg: 6
Args or kwargs can be passed without knowing what they are.
e.g. max(a, b, *args) 
4
e.g. dict(**kwargs) (same as dict(e=5, f=6, g=7)) returns: 
{'e': 5, 'g': 7, 'f': 6}

παράδειγμα 2

Μπορούμε επίσης να καλέσετε χρησιμοποιώντας μια άλλη λειτουργία, στην οποία απλά παρέχει a:

def bar(a):
    b, c, d, e, f = 2, 3, 4, 5, 6
    # dumping every local variable into foo as a keyword argument 
    # by expanding the locals dict:
    foo(**locals()) 

bar(100) εκτυπώσεις:

a is a required argument, and its value is 100
b not required, its default value is 10, actual value: 2
args is of type <type 'tuple'> and length 0
kwargs is of type <type 'dict'> and length 4
unknown kwarg - kw: c, arg: 3
unknown kwarg - kw: e, arg: 5
unknown kwarg - kw: d, arg: 4
unknown kwarg - kw: f, arg: 6
Args or kwargs can be passed without knowing what they are.
e.g. max(a, b, *args) 
100
e.g. dict(**kwargs) (same as dict(c=3, d=4, e=5, f=6)) returns: 
{'c': 3, 'e': 5, 'd': 4, 'f': 6}

Παράδειγμα 3: πρακτική χρήση σε διακοσμητές

Εντάξει, έτσι ίσως δεν είμαστε βλέπουμε τη χρησιμότητα ακόμα. Έτσι, φανταστείτε ότι έχετε πολλές λειτουργίες με περιττές κωδικό πριν ή / και μετά τον κωδικό διαφοροποίηση. Οι παρακάτω ονομάζεται λειτουργίες είναι ακριβώς ψευδο-κώδικα για επεξηγηματικούς σκοπούς.

def foo(a, b, c, d=0, e=100):
    # imagine this is much more code than a simple function call
    preprocess() 
    differentiating_process_foo(a,b,c,d,e)
    # imagine this is much more code than a simple function call
    postprocess()

def bar(a, b, c=None, d=0, e=100, f=None):
    preprocess()
    differentiating_process_bar(a,b,c,d,e,f)
    postprocess()

def baz(a, b, c, d, e, f):
    ... and so on

Θα μπορούσε να είναι σε θέση να χειριστεί το θέμα με διαφορετικό τρόπο, αλλά σίγουρα μπορεί να εξάγει την απόλυση με ένα διακοσμητή, και έτσι κάτω από το παράδειγμά μας δείχνει πώς *argsκαι **kwargsμπορεί να είναι πολύ χρήσιμο:

def decorator(function):
    '''function to wrap other functions with a pre- and postprocess'''
    @functools.wraps(function) # applies module, name, and docstring to wrapper
    def wrapper(*args, **kwargs):
        # again, imagine this is complicated, but we only write it once!
        preprocess()
        function(*args, **kwargs)
        postprocess()
    return wrapper

Και τώρα κάθε τυλιγμένο λειτουργία μπορεί να γραφτεί πολύ πιο συνοπτικά, όπως έχουμε υπολογιστεί από την απόλυση:

@decorator
def foo(a, b, c, d=0, e=100):
    differentiating_process_foo(a,b,c,d,e)

@decorator
def bar(a, b, c=None, d=0, e=100, f=None):
    differentiating_process_bar(a,b,c,d,e,f)

@decorator
def baz(a, b, c=None, d=0, e=100, f=None, g=None):
    differentiating_process_baz(a,b,c,d,e,f, g)

@decorator
def quux(a, b, c=None, d=0, e=100, f=None, g=None, h=None):
    differentiating_process_quux(a,b,c,d,e,f,g,h)

Και από factoring από τον κωδικό μας, η οποία *argsκαι **kwargsμας επιτρέπει να κάνουμε, μειώνουμε γραμμές κώδικα, να βελτιώσει την αναγνωσιμότητα και συντήρησης, και έχει την αποκλειστική κανονικές θέσεις για τη λογική στο πρόγραμμά μας. Αν πρέπει να αλλάξουμε οποιοδήποτε μέρος αυτής της δομής, έχουμε ένα μέρος για να κάνει κάθε αλλαγή.

Απαντήθηκε 14/10/2014 στις 17:34
πηγή χρήστη

ψήφοι
3

Εκτός από την λειτουργία κλήσεων, * args και ** kwargs είναι χρήσιμα στην τάξη ιεραρχίες και επίσης αποφεύγουν να χρειάζεται να γράψει __init__μέθοδο στην Python. Παρόμοια χρήση του μπορεί να δει σε πλαίσια όπως το κωδικό Django.

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

def __init__(self, *args, **kwargs):
    for attribute_name, value in zip(self._expected_attributes, args):
        setattr(self, attribute_name, value)
        if kwargs.has_key(attribute_name):
            kwargs.pop(attribute_name)

    for attribute_name in kwargs.viewkeys():
        setattr(self, attribute_name, kwargs[attribute_name])

Μια υποκατηγορία μπορεί στη συνέχεια να είναι

class RetailItem(Item):
    _expected_attributes = Item._expected_attributes + ['name', 'price', 'category', 'country_of_origin']

class FoodItem(RetailItem):
    _expected_attributes = RetailItem._expected_attributes +  ['expiry_date']

Η υποτάξη τότε να αρχικοποιείται ως

food_item = FoodItem(name = 'Jam', 
                     price = 12.0, 
                     category = 'Foods', 
                     country_of_origin = 'US', 
                     expiry_date = datetime.datetime.now())

Επίσης, μια υποκατηγορία με ένα νέο χαρακτηριστικό που έχει νόημα μόνο σε αυτή την περίπτωση υποκατηγορία μπορεί να καλέσει την κλάση βάσης __init__για να απαλλαγούν από τη ρύθμιση χαρακτηριστικά. Αυτό γίνεται μέσω * args και ** kwargs. kwargs χρησιμοποιείται κυρίως έτσι ώστε κώδικας είναι ευανάγνωστο χρησιμοποιώντας το όνομα επιχειρήματα. Για παράδειγμα,

class ElectronicAccessories(RetailItem):
    _expected_attributes = RetailItem._expected_attributes +  ['specifications']
    # Depend on args and kwargs to populate the data as needed.
    def __init__(self, specifications = None, *args, **kwargs):
        self.specifications = specifications  # Rest of attributes will make sense to parent class.
        super(ElectronicAccessories, self).__init__(*args, **kwargs)

η οποία μπορεί να instatiated ως

usb_key = ElectronicAccessories(name = 'Sandisk', 
                                price = '$6.00', 
                                category = 'Electronics',
                                country_of_origin = 'CN',
                                specifications = '4GB USB 2.0/USB 3.0')

Η πλήρης κωδικός είναι εδώ

Απαντήθηκε 16/08/2015 στις 04:23
πηγή χρήστη

ψήφοι
5

Στην Python 3.5, μπορείτε επίσης να χρησιμοποιήσετε αυτήν τη σύνταξη σε list, dict, tuple, και setεμφανίζει (και μερικές φορές ονομάζεται λεκτικές). Δείτε PEP 488: Πρόσθετες Αποσυσκευασία γενικεύσεις .

>>> (0, *range(1, 4), 5, *range(6, 8))
(0, 1, 2, 3, 5, 6, 7)
>>> [0, *range(1, 4), 5, *range(6, 8)]
[0, 1, 2, 3, 5, 6, 7]
>>> {0, *range(1, 4), 5, *range(6, 8)}
{0, 1, 2, 3, 5, 6, 7}
>>> d = {'one': 1, 'two': 2, 'three': 3}
>>> e = {'six': 6, 'seven': 7}
>>> {'zero': 0, **d, 'five': 5, **e}
{'five': 5, 'seven': 7, 'two': 2, 'one': 1, 'three': 3, 'six': 6, 'zero': 0}

Επίσης, επιτρέπει πολλαπλές iterables να αποσυμπιεστεί σε μία κλήση.

>>> range(*[1, 10], *[2])
range(1, 10, 2)

(Χάρη στην mgilson για τη σύνδεση PEP).

Απαντήθηκε 08/12/2015 στις 21:38
πηγή χρήστη

ψήφοι
34

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

def test(a,b,c):
     print(a)
     print(b)
     print(c)

test(1,2,3)
#output:
1
2
3

Έτσι, αυτό είναι ο ορισμός της συνάρτησης με θέσεις επιχειρήματα. Μπορείτε να καλέσετε με λέξη-κλειδί / ονομάστηκε επιχειρήματα, καθώς και:

def test(a,b,c):
     print(a)
     print(b)
     print(c)

test(a=1,b=2,c=3)
#output:
1
2
3

Τώρα ας μελετήσουμε ένα παράδειγμα του ορισμού συνάρτησης με επιχειρήματα λέξη-κλειδί :

def test(a=0,b=0,c=0):
     print(a)
     print(b)
     print(c)
     print('-------------------------')

test(a=1,b=2,c=3)
#output :
1
2
3
-------------------------

Μπορείτε να καλέσετε τη λειτουργία αυτή με θέσεις επιχειρήματα, καθώς και:

def test(a=0,b=0,c=0):
    print(a)
    print(b)
    print(c)
    print('-------------------------')

test(1,2,3)
# output :
1
2
3
---------------------------------

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

Τώρα ας μελετήσουμε το «*» φορέα και «**» χειριστή.

Παρακαλείστε να σημειώσετε ότι οι φορείς αυτοί μπορούν να χρησιμοποιηθούν σε 2 τομείς:

α) κλήση της συνάρτησης

β) ορισμό της συνάρτησης

Η χρήση των «*» φορέα και «**» φορέας εκμετάλλευσης στην κλήση της συνάρτησης.

Ας πάρει κατ 'ευθείαν σε ένα παράδειγμα και στη συνέχεια να το συζητήσουμε.

def sum(a,b):  #receive args from function calls as sum(1,2) or sum(a=1,b=2)
    print(a+b)

my_tuple = (1,2)
my_list = [1,2]
my_dict = {'a':1,'b':2}

# Let us unpack data structure of list or tuple or dict into arguments with help of '*' operator
sum(*my_tuple)   # becomes same as sum(1,2) after unpacking my_tuple with '*'
sum(*my_list)    # becomes same as sum(1,2) after unpacking my_list with  '*'
sum(**my_dict)   # becomes same as sum(a=1,b=2) after unpacking by '**' 

# output is 3 in all three calls to sum function.

Έτσι θυμηθείτε

όταν το «*» ή φορέας εκμετάλλευσης «**» χρησιμοποιείται σε μια κλήση συνάρτησης -

«*» Διαχειριστής αποσυμπιέζει τη δομή δεδομένων, όπως μια λίστα ή πλειάδα σε επιχειρήματα που απαιτείται εξ ορισμού λειτουργία.

«**» χειριστής αποσυμπιέζει ένα λεξικό σε επιχειρήματα που απαιτείται εξ ορισμού λειτουργία.

Τώρα ας μελετήσουμε την «*» χρήση φορέα στον ορισμό της συνάρτησης . Παράδειγμα:

def sum(*args): #pack the received positional args into data structure of tuple. after applying '*' - def sum((1,2,3,4))
    sum = 0
    for a in args:
        sum+=a
    print(sum)

sum(1,2,3,4)  #positional args sent to function sum
#output:
10

Σε λειτουργία ορισμός του «*» φορέας εκμετάλλευσης πακέτα τα ληφθέντα επιχειρήματα σε μια πλειάδα.

Τώρα, ας δούμε ένα παράδειγμα της «**» που χρησιμοποιείται στον ορισμό συνάρτησης:

def sum(**args): #pack keyword args into datastructure of dict after applying '**' - def sum({a:1,b:2,c:3,d:4})
    sum=0
    for k,v in args.items():
        sum+=v
    print(sum)

sum(a=1,b=2,c=3,d=4) #positional args sent to function sum

Σε λειτουργία ορισμό Το «**» φορέας εκμετάλλευσης πακέτα τα ληφθέντα επιχειρήματα σε ένα λεξικό.

Έτσι θυμηθείτε:

Σε μια κλήση συνάρτησης η «*» αποσυμπιέζει τη δομή δεδομένων της πλειάδας ή λίστας σε θέσεις ή λέξη-κλειδί επιχειρήματα για να γίνει δεκτός από τον ορισμό της συνάρτησης.

Σε λειτουργία αποκαλούν το «**» αποσυμπιέζει τη δομή δεδομένων του λεξικού σε θέσεις ή λέξη-κλειδί επιχειρήματα για να γίνει δεκτός από τον ορισμό της συνάρτησης.

Σε ένα ορισμό συνάρτησης η «*» πακέτα θέσης επιχειρήματα σε μια πλειάδα.

Σε ένα ορισμό συνάρτησης η «**» πακέτα επιχειρήματα λέξη-κλειδί σε ένα λεξικό.

Απαντήθηκε 20/01/2016 στις 11:40
πηγή χρήστη

ψήφοι
1

Ένα καλό παράδειγμα της χρήσης τόσο σε μια λειτουργία είναι:

>>> def foo(*arg,**kwargs):
...     print arg
...     print kwargs
>>>
>>> a = (1, 2, 3)
>>> b = {'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(*a,**b)
(1, 2, 3)
{'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(a,**b) 
((1, 2, 3),)
{'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(a,b) 
((1, 2, 3), {'aa': 11, 'bb': 22})
{}
>>>
>>>
>>> foo(a,*b)
((1, 2, 3), 'aa', 'bb')
{}
Απαντήθηκε 26/10/2016 στις 12:48
πηγή χρήστη

ψήφοι
6

Θέλω να δώσω ένα παράδειγμα που δεν έχουν αναφερθεί άλλα

* Μπορεί επίσης να αποσυμπιέσετε μια γεννήτρια

Ένα παράδειγμα από το έγγραφο python3

x = [1, 2, 3]
y = [4, 5, 6]

unzip_x, unzip_y = zip(*zip(x, y))

unzip_x θα είναι [1, 2, 3], unzip_y θα είναι [4, 5, 6]

Το φερμουάρ () δέχεται πολλαπλές iretable args, και να επιστρέψει μια γεννήτρια.

zip(*zip(x,y)) -> zip((1, 4), (2, 5), (3, 6))
Απαντήθηκε 08/11/2016 στις 16:50
πηγή χρήστη

ψήφοι
1

Αυτό το παράδειγμα θα σας βοηθήσει να θυμάστε *args, **kwargsακόμα και superκαι κληρονομιάς στην Python με τη μία.

class base(object):
    def __init__(self, base_param):
        self.base_param = base_param


class child1(base): # inherited from base class
    def __init__(self, child_param, *args) # *args for non-keyword args
        self.child_param = child_param
        super(child1, self).__init__(*args) # call __init__ of the base class and initialize it with a NON-KEYWORD arg

class child2(base):
    def __init__(self, child_param, **kwargs):
        self.child_param = child_param
        super(child2, self).__init__(**kwargs) # call __init__ of the base class and initialize it with a KEYWORD arg

c1 = child1(1,0)
c2 = child2(1,base_param=0)
print c1.base_param # 0
print c1.child_param # 1
print c2.base_param # 0
print c2.child_param # 1
Απαντήθηκε 26/11/2016 στις 21:09
πηγή χρήστη

ψήφοι
6

Ενώ οι χρήσεις για τις επιχειρήσεις αστέρι / ράντισμα έχουν επεκταθεί σε Python 3, μου αρέσει η παρακάτω πίνακα που αφορά στη χρήση αυτών των φορέων με τις λειτουργίες . Ο χειριστής ράντισμα (ες) μπορούν να χρησιμοποιηθούν τόσο μέσα από τη λειτουργία κατασκευή και στη λειτουργία κλήσης :

            In function *construction*      In function *call*
=======================================================================
          |  def f(*args):                 |  def f(a, b):
*args     |      for arg in args:          |      return a + b
          |          print(arg)            |  args = (1, 2)
          |  f(1, 2)                       |  f(*args)
----------|--------------------------------|---------------------------
          |  def f(a, b):                  |  def f(a, b):
**kwargs  |      return a + b              |      return a + b
          |  def g(**kwargs):              |  kwargs = dict(a=1, b=2)
          |      return f(**kwargs)        |  f(**kwargs)
          |  g(a=1, b=2)                   |
-----------------------------------------------------------------------

Αυτό πραγματικά ακριβώς χρησιμεύει για να συνοψίσει Lorin Hochstein του απάντηση , αλλά θεωρώ ότι είναι χρήσιμο.

Απαντήθηκε 30/11/2017 στις 18:28
πηγή χρήστη

ψήφοι
0

* Args = * κεκλιμένος = όλα τα στοιχεία σε μια Λίστα

** args = ** εθιμένος = όλα τα στοιχεία σε ένα dict

Απαντήθηκε 08/12/2017 στις 01:36
πηγή χρήστη

ψήφοι
0

*argsκαι **kwargs: να επιτρέψει σε σας για να περάσετε ένα μεταβλητό αριθμό ορισμάτων σε μια συνάρτηση.

*args: Χρησιμοποιείται για την αποστολή μη keyworded μεταβλητού μήκους λίστα παραμέτρων στη συνάρτηση:

def args(normal_arg, *argv):
    print ("normal argument:",normal_arg)

    for arg in argv:
        print("Argument in list of arguments from *argv:", arg)

args('animals','fish','duck','bird')

Θα παράγει:

normal argument: animals
Argument in list of arguments from *argv: fish
Argument in list of arguments from *argv: duck
Argument in list of arguments from *argv: bird

**kwargs*

**kwargsσας δίνει τη δυνατότητα να περάσει keyworded μεταβλητού μήκους επιχειρήματα σε λειτουργία. Θα πρέπει να χρησιμοποιήσετε **kwargsαν θέλετε να χειριστεί το όνομα επιχειρήματα σε λειτουργία.

def who(**kwargs):
    if kwargs is not None:
        for key, value in kwargs.items():
            print ("Your %s is %s." %(key,value))

who (name="Nikola", last_name="Tesla", birthday = "7.10.1856", birthplace = "Croatia")  

Θα παράγει:

Your name is Nikola.
Your last_name is Tesla.
Your birthday is 7.10.1856.
Your birthplace is Croatia.
Απαντήθηκε 01/05/2018 στις 12:54
πηγή χρήστη

ψήφοι
0

Για όσους από εσάς να μάθουν από παραδείγματα:

def f(normal_input, *args, **kw):
    # Print the length of args and kw in a friendly format
    print("len(args) = {} and len(kw) = {}".format(len(args), len(kw)))

l = list(range(5))
d = {"k0":"v0", "k1":"v1"}

f(42, 0, 1, 2, 3, 4, 5) # len(args) = 6 and len(kw) = 0

f(42, l) # len(args) = 1 and len(kw) = 0
f(42, d) # len(args) = 1 and len(kw) = 0

f(42, *l) # len(args) = 5 and len(kw) = 0
f(42, *d) # len(args) = 2 and len(kw) = 0

try:
    f(42, **l) # Gives an error
except TypeError:
    print("l in f(**l) is not a dictionary!")

f(42, **d) # len(args) = 0 and len(kw) = 2

# Without explicitly feeding normal_input
# l[0] becomes normal_input
f(*l) # len(args) = 4 and len(kw) = 0

# Let's try everything now
f(42, 420, 4200, *l, **d) # len(args) = 7 and len(kw) = 2

Παρατηρήστε το πρώτο επιχείρημα είναι η normal_input, το 2ο, 3ο, και * l είναι τα επόμενα 7 επιχειρήματα.

Απαντήθηκε 22/05/2018 στις 07:03
πηγή χρήστη

ψήφοι
0

* σημαίνει λάβετε μεταβλητή επιχειρήματα λίστα

** σημαίνει λάβετε μεταβλητή επιχειρήματα λεξικό

Χρησιμοποιείται όπως το παρακάτω:

1) ενιαίο *

def foo(*args):
    for arg in args:
        print(arg)

foo("two", 3)

Παραγωγή:

two
3

2) Τώρα **

def bar(**kwargs):
    for key in kwargs:
        print(key, kwargs[key])

bar(dic1="two", dic2=3)

Παραγωγή:

dic1 two
dic2 3
Απαντήθηκε 07/08/2018 στις 18:28
πηγή χρήστη

ψήφοι
0
  • def foo(param1, *param2):είναι μια μέθοδος μπορεί να δεχτεί αυθαίρετο αριθμό των αξιών για *param2,
  • def bar(param1, **param2): είναι μια μέθοδος μπορεί να δεχθεί αυθαίρετο αριθμό αξιών με πλήκτρα για *param2
  • param1 είναι μια απλή παράμετρος.

Για παράδειγμα, η σύνταξη για την εφαρμογή varargs σε Java ως εξής:

accessModifier methodName(datatype… arg) {
    // method body
}
Απαντήθηκε 02/09/2018 στις 05:14
πηγή χρήστη

ψήφοι
0

TL? DR

Συσκευάζει τα επιχειρήματα που περνούν στη συνάρτηση στο listκαι dictαντίστοιχα μέσα στο σώμα λειτουργία. Όταν μια υπογραφή λειτουργία όπως αυτό:

def func(*args, **kwds):
    # do stuff

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

func("this", "is a list of", "non-keyowrd", "arguments", keyword="ligma", options=[1,2,3])

τώρα μέσα στο σώμα λειτουργία, όταν η λειτουργία αυτή ονομάζεται, υπάρχουν δύο τοπικές μεταβλητές, argsη οποία είναι μια λίστα που έχει αξία ["this", "is a list of", "non-keyword", "arguments"]και kwdsτο οποίο είναι ένα dictπου έχει αξία{"keyword" : "ligma", "options" : [1,2,3]}


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

def f(a, b, c, d=1, e=10):
    # do stuff

μπορείτε να καλέσετε με το από αποσυμπίεση iterables ή αντιστοιχίσεις έχετε στην κλήση πεδίο:

iterable = [1, 20, 500]
mapping = {"d" : 100, "e": 3}
f(*iterable, **mapping)
# That call is equivalent to
f(1, 20, 500, d=100, e=3)
Απαντήθηκε 02/04/2019 στις 12:43
πηγή χρήστη

ψήφοι
0

Με βάση nickd του απάντηση ...

def foo(param1, *param2):
    print(param1)
    print(param2)


def bar(param1, **param2):
    print(param1)
    print(param2)


def three_params(param1, *param2, **param3):
    print(param1)
    print(param2)
    print(param3)


print(foo(1, 2, 3, 4, 5))
print("\n")
print(bar(1, a=2, b=3))
print("\n")
print(three_params(1, 2, 3, 4, s=5))

Παραγωγή:

1
(2, 3, 4, 5)

1
{'a': 2, 'b': 3}

1
(2, 3, 4)
{'s': 5}

Βασικά, οποιοσδήποτε αριθμός θέσης επιχειρήματα μπορούν να χρησιμοποιήσουν * args και κάθε ονομάζεται επιχειρήματα (ή kwargs γνωστός και ως επιχειρήματα λέξη-κλειδί) μπορούν να χρησιμοποιήσουν ** kwargs.

Απαντήθηκε 10/07/2019 στις 05:59
πηγή χρήστη

ψήφοι
0

Συμφραζόμενα

  • python 3.x
  • αποσυσκευασία με **
  • χρήση με μορφοποίηση κορδόνι

Χρησιμοποιήστε το με μορφοποίηση κορδόνι

Εκτός από τις απαντήσεις σε αυτό το νήμα, εδώ είναι μια άλλη λεπτομέρεια που δεν αναφέρονται αλλού. Αυτό επεκτείνεται στην απάντηση του Μπραντ Σολομώντα

Αποσυσκευασία με **είναι επίσης χρήσιμη όταν χρησιμοποιείτε Python str.format.

Αυτό είναι κάπως παρόμοιο με αυτό που μπορείτε να κάνετε με python f-strings f-string , αλλά με την πρόσθετη επιβάρυνση της με την οποία μια dict για να κρατήσει τις μεταβλητές (f-string δεν απαιτεί dict).

Γρήγορη Παράδειγμα

  ## init vars
  ddvars = dict()
  ddcalc = dict()
  pass
  ddvars['fname']     = 'Huomer'
  ddvars['lname']     = 'Huimpson'
  ddvars['motto']     = 'I love donuts!'
  ddvars['age']       = 33
  pass
  ddcalc['ydiff']     = 5
  ddcalc['ycalc']     = ddvars['age'] + ddcalc['ydiff']
  pass
  vdemo = []

  ## ********************
  ## single unpack supported in py 2.7
  vdemo.append('''
  Hello {fname} {lname}!

  Today you are {age} years old!

  We love your motto "{motto}" and we agree with you!
  '''.format(**ddvars)) 
  pass

  ## ********************
  ## multiple unpack supported in py 3.x
  vdemo.append('''
  Hello {fname} {lname}!

  In {ydiff} years you will be {ycalc} years old!
  '''.format(**ddvars,**ddcalc)) 
  pass

  ## ********************
  print(vdemo[-1])

Απαντήθηκε 06/12/2019 στις 19:36
πηγή χρήστη

ψήφοι
0

TL? DR

Παρακάτω είναι 6 διαφορετικές περιπτώσεις χρήσης *και **του προγραμματισμού python:

  1. Για να αποδεχτείτε οποιοδήποτε αριθμό θέσης επιχειρήματα: def foo(*args): pass εδώ fooδέχεται οποιοδήποτε αριθμό θέσης επιχειρήματα, δηλαδή, οι ακόλουθες κλήσεις είναι έγκυρη foo(1),foo(1, 'bar')
  2. Για να δεχθεί οποιαδήποτε σειρά επιχειρημάτων λέξη-κλειδί: def foo(**kwargs): pass εδώ «foo» δέχεται οποιοδήποτε αριθμό των επιχειρημάτων λέξη-κλειδί, δηλαδή, οι ακόλουθες κλήσεις είναι έγκυρη foo(name='Tom'),foo(name='Tom', age=33)
  3. Για να αποδεχτείτε οποιοδήποτε αριθμό θέσης και λέξη-κλειδί επιχειρήματα: def foo(*args, **kwargs): pass εδώ fooδέχεται οποιοδήποτε αριθμό θέσης και λέξη-κλειδί επιχειρήματα, δηλαδή, οι ακόλουθες κλήσεις είναι έγκυρη foo(1,name='Tom'),foo(1, 'bar', name='Tom', age=33)
  4. Για να επιβάλει λέξη-κλειδί μόνο επιχειρήματα (χρήση *): def foo(pos1, pos2, *, kwarg1): pass εδώ *μέσα ότι foo δέχονται μόνο ορίσματα με λέξεις κλειδιά μετά pos2, ως εκ τούτου, foo(1, 2, 3)αυξάνει TypeError, αλλά foo(1, 2, kwarg1=3)είναι εντάξει.
  5. Για να εκφράσει καμία περαιτέρω ενδιαφέρον για περισσότερες θέσεις επιχειρήματα (Σημείωση: αυτή είναι μια σύμβαση μόνο): def foo(bar, baz, *_): pass μέσα (κατά συνθήκη) fooμόνο χρήσεις barκαι bazεπιχειρήματα εργασίας και θα αγνοήσει τους άλλους.
  6. Για να εκφράσει καμία περαιτέρω ενδιαφέρον για τα επιχειρήματα περισσότερες λέξεις-κλειδιά (Σημείωση: αυτή είναι μια σύμβαση μόνο): def foo(bar, baz, **_): pass μέσα (κατά συνθήκη) fooμόνο χρήσεις barκαι bazεπιχειρήματα εργασίας και θα αγνοήσει τους άλλους.

BONUS: Από pyton 3.8 και μετά μπορεί κανείς να χρησιμοποιήσει /στο ορισμό της συνάρτησης για την επιβολή θέσης μόνο παραμέτρους. Στο παρακάτω παράδειγμα, παράμετροι α και b είναι θέσης-μόνο , ενώ c ή d μπορούν να είναι θέσης ή λέξη-κλειδί, και e ή f απαιτείται να είναι λέξεις-κλειδιά:

def f(a, b, /, c, d, *, e, f)
Απαντήθηκε 07/01/2020 στις 17:37
πηγή χρήστη

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