একটি ফাংশন কলে স্টার অপারেটরের অর্থ কী?


621

কী *অপারেটর যেমন মত কোড হিসাবে, পাইথন এর অর্থ zip(*x)বা f(**k)?

  1. এটি দোভাষীর অভ্যন্তরীণভাবে কীভাবে পরিচালনা করা হয়?
  2. এটি কি আদৌ পারফরম্যান্সকে প্রভাবিত করে? এটি দ্রুত বা ধীর?
  3. এটি কখন কার্যকর এবং কখন তা নয়?
  4. এটি কোনও ফাংশন ঘোষণায় বা একটি কলে ব্যবহার করা উচিত?

4
আমি মনে করি এটি "* ফাংশন কল সিনট্যাক্স" হিসাবে চিহ্নিত করা উচিত। তারা অপারেটর নয়, যদিও এটি বিভ্রান্ত হয়ে উঠবে কারণ এমন একটি *এবং **অপারেটর রয়েছে যার এই সিনট্যাক্সের সাথে কোনও সম্পর্ক নেই।
আয়ান বাইকিং

4
@ আইয়ান বাইকিং: আপনি পুরো অধিকার, * এবং ** যুক্তি তালিকার খাঁটি বাক্য গঠন (টোকেন)।
পি। অর্টিজ

25
f(**k)আপনি যদি আমাকে জিজ্ঞাসা করেন তবে ভুল থেকে বেরিয়ে আসে :)
জিন-ফ্রান্সোয়েস ফ্যাব্রে


4
ভিটিআর - এটি প্যারামিটারগুলির জন্য ** (ডাবল তারকা / নক্ষত্র) এবং * (তারা / তারকাচিহ্ন) কী করে তার নকল নয় ? যেহেতু এই প্রশ্নটি কেবলমাত্র পরামিতি সম্পর্কে, যদিও উত্তরগুলি ফাংশন কলগুলিও কভার করে। এটি কম জনপ্রিয় এবং শীর্ষের উত্তর কম সম্পূর্ণ হওয়ায় ফাংশন কলের এস্টারিক এই প্রশ্নের সদৃশ হিসাবে চিহ্নিত করা উচিত।
wjandrea

উত্তর:


953

একক তারা *ক্রম / সংগ্রহটি অবস্থানগত আর্গুমেন্টে আনপ্যাক করে, তাই আপনি এটি করতে পারেন:

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

এটি আপনাকে বিপুল সংখ্যক alচ্ছিক প্যারামিটারগুলি ঘোষণা না করে নির্দিষ্ট করার অনুমতি দিতে পারে।

এবং আবারও, আপনি একত্রিত করতে পারেন:

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

4
কেন আপনার এটির প্রয়োজন হবে, সরবরাহকৃত তালিকাটি প্রসারিত না করে কেবল ফাংশনটি পুনরাবৃত্তি করতে পারে না?
মার্টিন বেকেট

29
অবশ্যই, তবে তারপরে আপনাকে এটিকে কল করতে হবে: s = sum((1, 2, 3, 4, 5))বা s = sum([1, 2, 3, 4, 5]), *valuesবিকল্পটি কলটিকে এমন অনেকগুলি আর্গুমেন্ট লাগে বলে মনে করে, তবে সেগুলি ফাংশন কোডের জন্য একটি সংকলনে সজ্জিত।
লাসে ভি। কার্লসেন

11
এখানে আসল উপকারিতা: আপনি এমন ফাংশন লিখতে পারেন যা অন্যথায় সম্ভব হয় না যদি আপনার চলক সংখ্যক যুক্তি যুক্ত করতে হয়। উদাহরণস্বরূপ, সি এর প্রিন্টফ ফাংশন, যার মধ্যে 1+ এন আর্গুমেন্ট রয়েছে, যে কোনও প্রারম্ভিক প্রোগ্রামারকে অনুশীলন হিসাবে লিখতে পারা যায়। পাইথনে, একজন শিক্ষানবিস ডিএফ প্রিন্টফ (স্ট্রিং_টেম্পলেট, * আরগস) লিখতে এবং এগিয়ে যেতে পারে।
আইসআর্ডার

4
আপনি যদি (দুর্ঘটনাক্রমে সম্ভবত: পি) একটি অভিধান দুটি করে না দিয়ে কেবল একটি * দিয়ে প্যাক করেন তবে কী হবে? এটি কিছু করার জন্য মনে হয়, মনে হয় একটি টিপল বেরিয়ে আসে তবে এটি কী তা স্পষ্ট নয়। (সম্পাদনা করুন: ঠিক আছে আমি মনে করি উত্তরটি হ'ল এটি কেবল কীগুলি প্যাক করে, মানগুলি বাদ দেওয়া হয়)
বেন ফার্মার

4
শেষ উদাহরণটি বোঝায় যে * এবং ** কেবল আনপ্যাকিংই করছে না, প্যাকিংও করছে! এই দুর্দান্ত পৃষ্ঠাটি কোডিংএম.প্লেগ্রাউন্ডগুলি
500/…

46

একটি ছোট পয়েন্ট: এগুলি অপারেটর নয়। অপারেটরগুলি বিদ্যমান মানগুলি থেকে নতুন মান তৈরি করতে এক্সপ্রেশন হিসাবে ব্যবহৃত হয় (উদাহরণস্বরূপ 1+ 2 হয়ে যায় here


6
দ্রষ্টব্য যে পাইথন ডকুমেন্টেশন কল করতে পারে * এই প্রসঙ্গে একটি অপারেটর; আমি একমত, এ ধরণের বিভ্রান্তিকর।
ক্রিস্টোফ

ধন্যবাদ আমি অজগর রেফারেন্স ডকুমেন্টেশনে এটির একটি পরিষ্কার বিবরণ খুঁজছি এবং এখনও এটি দেখতে পাচ্ছি না। সুতরাং ফাংশন কলগুলির নিয়মটি মূলত এটি একটি "*" বা "**" যা একটি ফাংশন কলের মধ্যে একটি অভিব্যক্তিটির শুরুতে এই ধরণের প্রসার ঘটায়?
nealmcb

20

আপনি যখন কোনও ফাংশন কল 'সঞ্চয়' করতে চান তখন আমি এটি বিশেষভাবে দরকারী বলে মনে করি।

উদাহরণস্বরূপ, ধরুন আমার একটি ফাংশন 'অ্যাড' এর জন্য কিছু ইউনিট পরীক্ষা আছে:

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]) এর মতো কিছু করা ছাড়া, যা কুশ্রী। এছাড়াও, যদি ভেরিয়েবলের একটি ভেরিয়েবল সংখ্যা থাকে তবে কোডটি আপনার যদি প্রয়োজন সমস্ত if-বিবৃতি দিয়ে বেশ কুৎসিত হতে পারে।

অন্য যে জায়গাতে এটি দরকারী তা হ'ল ফ্যাক্টরি অবজেক্ট (আপনার জন্য বস্তু তৈরি করা বস্তু) সংজ্ঞায়িত করার জন্য। ধরুন আপনার কোনও ক্লাস কারখানা রয়েছে, এটি কারকে বস্তু তৈরি করে এবং সেগুলি ফেরত দেয়। আপনি এটিকে এটি তৈরি করতে পারেন যাতে মাইফ্যাক্টরি.মেক_কার ('লাল', 'বিএমডাব্লু', '৩৩৫ পিক্স') কার ('লাল', 'বিএমডাব্লু', '৩৩৫ পিক্স') তৈরি করে, তারপরে এটি ফিরিয়ে দেয়।

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

আপনি যখন সুপার ক্লাসের কনস্ট্রাক্টরকে কল করতে চান এটিও কার্যকর।


4
আমি আপনার উদাহরণ পছন্দ। তবে, আমি মনে করি -1 + 3 == 2।
একসোর্টস

4
আমি ইচ্ছাকৃতভাবে সেখানে কিছু ফেললাম যা ব্যর্থ হবে :)
ডোনাল্ড মিনার

19

একে বর্ধিত কল সিনট্যাক্স বলা হয়। ডকুমেন্টেশন থেকে :

যদি সিনট্যাক্স * এক্সপ্রেশনটি ফাংশন কলে উপস্থিত হয়, এক্সপ্রেশন অবশ্যই একটি ক্রম মূল্যায়ন করতে হবে। এই অনুক্রমের উপাদানগুলি এমনভাবে বিবেচনা করা হয় যেন তারা অতিরিক্ত অবস্থানগত যুক্তি ছিল; যদি কোনও স্থিতিযুক্ত যুক্তি x1, ..., xN, এবং এক্সপ্রেশন y1, ..., yM এর মূল্যায়ন করে তবে এটি এম + এন অবস্থানগত আর্গুমেন্ট x1, ..., xN, y1, এর সাথে কল করার সমান। .., ওয়াইএম

এবং:

যদি সিনট্যাক্স ** এক্সপ্রেশনটি ফাংশন কলটিতে উপস্থিত হয়, এক্সপ্রেশনটিকে অবশ্যই একটি ম্যাপিংয়ের মূল্যায়ন করতে হবে, এর সামগ্রীগুলি অতিরিক্ত কীওয়ার্ড আর্গুমেন্ট হিসাবে বিবেচিত হবে। কোনও কীওয়ার্ড উভয় এক্সপ্রেশন এবং স্পষ্ট কীওয়ার্ড আর্গুমেন্ট হিসাবে উপস্থিত হওয়ার ক্ষেত্রে, একটি টাইপরর ব্যতিক্রম উত্থাপিত হয়।


4
কেবল পাঠ্যপুস্তকের উত্তরে একটি পাদটীকা যুক্ত করুন - সিন্টেক্সটিক্যাল সমর্থন আসার আগে অন্তর্নির্মিত apply()ফাংশনটির সাথে একই কার্যকারিতা অর্জন করা হয়েছিল
জেরেমি ব্রাউন

18

একটি ফাংশন কলে একক তারকা পৃথক আর্গুমেন্ট মধ্যে একটি তালিকা দেখা যাচ্ছে (যেমন zip(*x)হিসাবে একই zip(x1,x2,x3)যদি x=[x1,x2,x3]) এবং ডবল তারকা পৃথক শব্দ আর্গুমেন্ট মধ্যে একটি অভিধান সক্রিয় (যেমন f(**k)হিসাবে একই f(x=my_x, y=my_y)যদি k = {'x':my_x, 'y':my_y}

কোনও ফাংশন সংজ্ঞায় এটি অন্যান্য উপায়ে: একক তারা একটি স্বেচ্ছাসেবী সংখ্যাকে যুক্তিগুলিকে একটি তালিকায় পরিণত করে এবং ডাবল শুরুটি মূলশব্দ যুক্তিগুলির একটি স্বেচ্ছাসেবী সংখ্যাকে অভিধানে পরিণত করে। উদাহরণস্বরূপ def foo(*x)"foo একটি আর্গুমেন্ট সংখ্যক আর্গুমেন্ট গ্রহণ করে এবং তারা তালিকার মাধ্যমে এক্স অ্যাক্সেসযোগ্য হবে (উদাহরণস্বরূপ যদি ব্যবহারকারী কল করেন foo(1,2,3), xহবে [1,2,3])" এবং এর def bar(**k)অর্থ "বার কীওয়ার্ড আর্গুমেন্টের একটি স্বেচ্ছাসেবী সংখ্যা নেয় এবং অভিধানের মাধ্যমে তারা অ্যাক্সেসযোগ্য হবে (অর্থাত ব্যবহারকারী কল যদি bar(x=42, y=23), kহতে হবে {'x': 42, 'y': 23}) "।


4
একটি (খুব) দেরী মন্তব্য, কিন্তু আমি বিশ্বাস করি def foo(*x)x থেকে একটি টিপল দেয়, তালিকা নয়।
jeremycg
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.