python - ماذا يعني مشغل النجمة؟




syntax parameter-passing identifier kwargs (5)

يقوم النجم المفرد * بتفكيك التسلسل / التجميع إلى وسيطات موضعية ، بحيث يمكنك القيام بذلك:

def sum(a, b):
    return a + b

values = (1, 2)

s = sum(*values)

سيؤدي ذلك إلى فك مجموعة البيانات بحيث يتم تنفيذها فعليًا على النحو التالي:

s = sum(1, 2)

النجم المزدوج ** يفعل نفس الشيء ، فقط باستخدام قاموس ومن ثمَّ يتم ذكره في الوسائط:

values = { 'a': 1, 'b': 2 }
s = sum(**values)

يمكنك أيضًا الجمع بين:

def sum(a, b, c, d):
    return a + b + c + d

values1 = (1, 2)
values2 = { 'c': 10, 'd': 15 }
s = sum(*values1, **values2)

سوف تنفذ على النحو التالي:

s = sum(1, 2, c=10, d=15)

انظر أيضا القسم 4.7.4 - تفريغ حجة قوائم وثائق بيثون.

بالإضافة إلى ذلك ، يمكنك تحديد وظائف لأخذ وسيطات *x و **y ، وهذا يسمح للوظيفة بقبول أي عدد من الوسيطات الموضعية و / أو المسماة التي لم يتم تسميتها بشكل محدد في التعريف.

مثال:

def sum(*values):
    s = 0
    for v in values:
        s = s + v
    return s

s = sum(1, 2, 3, 4, 5)

أو مع ** :

def get_a(**values):
    return values['a']

s = get_a(a=1, b=2)      # returns 1

هذا يمكن أن يسمح لك بتحديد عدد كبير من المعلمات الاختيارية دون الحاجة إلى إعلانها.

ومرة أخرى ، يمكنك الجمع بين:

def sum(*values, **options):
    s = 0
    for i in values:
        s = s + i
    if "neg" in options:
        if options["neg"]:
            s = -s
    return s

s = sum(1, 2, 3, 4, 5)            # returns 15
s = sum(1, 2, 3, 4, 5, neg=True)  # returns -15
s = sum(1, 2, 3, 4, 5, neg=False) # returns 15

ممكن تكرار:
ماذا يفعل * arg و ** kwargs يعني؟

ماذا يعني المشغل * في بايثون ، كما هو الحال في الكود مثل zip(*x) أو f(**k) ؟

  1. كيف يتم التعامل داخليا في المترجم؟
  2. هل يؤثر على الأداء على الإطلاق؟ هل هو سريع أم بطيء؟
  3. متى يكون ذلك مفيدًا ومتى لا يكون كذلك؟
  4. هل يجب استخدامه في تصريح الوظيفة أم في المكالمة؟

أجد هذا مفيدًا بشكل خاص عندما تريد "تخزين" مكالمة وظيفية.

على سبيل المثال ، لنفترض أن لدي بعض اختبارات الوحدة لوظيفة "إضافة":

def add(a, b): return a + b
tests = { (1,4):5, (0, 0):0, (-1, 3):3 }
for test, result in tests.items():
   print 'test: adding', test, '==', result, '---', add(*test) == result

لا توجد طريقة أخرى للاتصال بإضافة ، بخلاف القيام يدويًا بشيء مثل إضافة (اختبار [0] ، اختبار [1]) ، وهو أمر قبيح. أيضا ، إذا كان هناك عدد متغير من المتغيرات ، يمكن أن تحصل على رمز قبيح جدا مع جميع البيانات ، إذا كنت في حاجة.

مكان آخر مفيد هذا هو تعريف كائنات المصنع (الكائنات التي تنشئ كائنات من أجلك). افترض أن لديك بعض مصنع الصف ، الذي يجعل كائنات السيارات ويعيدها. يمكنك أن تجعل من myFactory.make_car ('red' ، 'bmw' ، '335ix') سيارة ('red' ، 'bmw' ، '335ix') ، ثم تقوم بإرجاعها.

def make_car(*args):
   return Car(*args)

هذا مفيد أيضاً عندما تريد استدعاء مُنشئ superclass '.


في استدعاء دالة ، يحول النجم الواحد قائمة إلى حجج منفصلة (على سبيل المثال ، zip(*x) هو نفس zip(x1,x2,x3) إذا كان x=[x1,x2,x3] ) والنجم المزدوج يتحول إلى قاموس إلى وسيطات الكلمة الرئيسية f(x=my_x, y=my_y) (على سبيل المثال f(**k) هي نفس f(x=my_x, y=my_y) إذا كان k = {'x':my_x, 'y':my_y} .

في تعريف الدوال ، يكون العكس هو التالي: يقوم النجم المفرد بتحويل عدد عشوائي من الوسيطات إلى قائمة ، ويؤدي البدء المزدوج إلى تحويل عدد عشوائي من وسيطات الكلمات الرئيسية إلى قاموس. مثال def foo(*x) يعني "foo يأخذ عددًا عشوائيًا من الحجج وسيتم الوصول إليها من خلال القائمة x (أي إذا كان المستخدم يتصل بـ foo(1,2,3) ، x سيكون [1,2,3] ) " def bar(**k) يعني" شريط يأخذ عددًا عشوائيًا من وسيطات الكلمات الرئيسية وسيتم الوصول إليه من خلال القاموس k (أي إذا كان bar(x=42, y=23) المكالمات للمستخدم bar(x=42, y=23) ، سيكون k هو {'x': 42, 'y': 23} ) ".


نقطة صغيرة واحدة: هذه ليست المشغلين. يتم استخدام عوامل التشغيل في التعبيرات لإنشاء قيم جديدة من القيم الموجودة (1 + 2 يصبح 3 ، على سبيل المثال. * و ** هنا جزءًا من بناء جملة إعلانات ومكالمات الوظائف.


حسنًا ، أرى أنه في cin الثاني قمت بالتبديل من cin إلى scanf ، وهو أول اقتراح سأقوم به (cin هو sloooooooooooow). الآن ، إذا قمت بالتبديل من scanf إلى fgets ، سترى دفعة أخرى في الأداء: fgets هي أسرع وظيفة C ++ لإدخال السلسلة.

راجع للشغل ، لم أكن أعرف شيئا عن ذلك المزامنة ، لطيفة. ولكن لا يزال عليك محاولة fgets .







python syntax parameter-passing identifier kwargs