পাইথনে ** কাওয়ারগুলি ব্যবহারের সঠিক উপায়


452

**kwargsডিফল্ট মানগুলির ক্ষেত্রে পাইথনে ব্যবহার করার যথাযথ উপায় কী ?

kwargsএকটি অভিধান রিটার্ন করে তবে ডিফল্ট মান নির্ধারণের সর্বোত্তম উপায় কোনটি আছে বা আছে? আমার কি কেবল অভিধান হিসাবে এটি অ্যাক্সেস করা উচিত? ফাংশন পেতে ব্যবহার করবেন?

class ExampleClass:
    def __init__(self, **kwargs):
        self.val = kwargs['val']
        self.val2 = kwargs.get('val2')

একটি সাধারণ প্রশ্ন, তবে একটি যা আমি ভাল সংস্থান খুঁজে পাচ্ছি না। লোকেরা কোডে এটি বিভিন্ন উপায়ে করে যা আমি দেখেছি এবং কী ব্যবহার করবেন তা জানা শক্ত hard

উত্তর:


468

get()অভিধানে নেই এমন কীগুলির জন্য আপনি একটি ডিফল্ট মান পাস করতে পারেন :

self.val2 = kwargs.get('val2',"default value")

তবে, আপনি যদি কোনও নির্দিষ্ট ডিফল্ট মান সহ একটি নির্দিষ্ট যুক্তি ব্যবহার করার পরিকল্পনা করেন তবে প্রথমে নামযুক্ত যুক্তি ব্যবহার করবেন না কেন?

def __init__(self, val2="default value", **kwargs):

16
আমি কেবলমাত্র প্রয়োজনীয় আর্গুমেন্টের জন্য অবস্থানগত আর্গুমেন্টগুলি ব্যবহার করতে চাই, এবং যুক্তিগুলির জন্য কোয়ার্গস যা নির্দিষ্ট করে দেওয়া বা নাও করা যায়, তবে এটি একটি ডিফল্ট মান পেতে সহায়ক। কাওয়ার্গস দুর্দান্ত কারণ আপনি যে কোনও পছন্দমতো আপনার অর্গ জমা দিতে পারেন। অবস্থানগত যুক্তি আপনাকে সেই স্বাধীনতা দেয় না।
কেকোয়া

95
আপনার পছন্দ মতো যে কোনও আদেশে আপনি নাম যুক্তিগুলি পাস করতে পারেন। আপনি যদি নামগুলি ব্যবহার না করেন তবে কেবলমাত্র পদগুলিতেই মেনে চলতে হবে - যেটি কোয়ার্গসের ক্ষেত্রে আপনাকে করতে হবে। বরং, কাওয়ার্গের বিরোধী হিসাবে নামযুক্ত যুক্তি ব্যবহার করা আপনাকে নামগুলি ব্যবহার না করার অতিরিক্ত স্বাধীনতা দেয় - তবে, আপনাকে আদেশটি রাখতে হবে।
বালফা

13
@ কেকোয়া: আপনি যে কোনও আদেশ পছন্দ হিসাবে সর্বদা নাম যুক্তি জমা দিতে পারেন। এই নমনীয়তা পেতে আপনাকে ** কাওয়ারগুলি ব্যবহার করতে হবে না।
এস .লট

13
পাইলট এটিকে কুয়ার্গ ব্যবহার করার জন্য খারাপ রূপ হিসাবে চিহ্নিত করে __init__()। কেউ ব্যাখ্যা করতে পারেন কেন এটি লিট-যোগ্য যোগ্য লঙ্ঘন?
হুগডব্রাউন


271

বেশিরভাগ উত্তর যখন বলছে যে, উদাহরণস্বরূপ,

def f(**kwargs):
    foo = kwargs.pop('foo')
    bar = kwargs.pop('bar')
    ...etc...

হিসাবে একই"

def f(foo=None, bar=None, **kwargs):
    ...etc...

এটা সত্য নয়। পরবর্তী ক্ষেত্রে, fহিসাবে ডাকা যেতে পারে f(23, 42), পূর্ববর্তী ক্ষেত্রে কেবল নামযুক্ত যুক্তি গ্রহণ করে - কোনও অবস্থানিক কল নেই। প্রায়শই আপনি কলারের সর্বাধিক নমনীয়তাটিকে মঞ্জুর করতে চান এবং তাই দ্বিতীয় উত্তর হিসাবে সর্বাধিক উত্তরগুলি দৃ .়ভাবে বলা হয় তত বেশি: তবে তা সবসময় হয় না। যখন আপনি অনেকগুলি alচ্ছিক প্যারামিটারগুলি গ্রহণ করেন যার মধ্যে সাধারণত কয়েকটি পাস করা হয়, তবে এটি নামযুক্ত যুক্তিগুলিকে ব্যবহার করার জন্য বাধ্য করার জন্য একটি দুর্দান্ত ধারণা (আপনার কল সাইটগুলিতে দুর্ঘটনা এবং অপঠনযোগ্য কোড এড়ানো!) হতে পারে - threading.Threadএটি একটি উদাহরণ। প্রথম রূপটি কীভাবে আপনি পাইথন 2 তে এটি প্রয়োগ করেন।

বাগ্ধারা এত গুরুত্বপূর্ণ পাইথন 3 এটা এখন বিশেষ সমর্থনকারী সিনট্যাক্স আছে: একটি একক হওয়ার পর প্রত্যেক যুক্তি *মধ্যে defস্বাক্ষর শব্দ-শুধুমাত্র যে, একটি অবস্থানগত আর্গুমেন্ট হিসাবে পাস করা যাবে না, কিন্তু শুধুমাত্র একটি নামাঙ্কিত এক হিসাবে হয়। পাইথন 3 এ আপনি উপরেরটি কোড করতে পারেন:

def f(*, foo=None, bar=None, **kwargs):
    ...etc...

আসলে, পাইথন 3 এ আপনার কী-ওয়ার্ল্ড-যুক্তি থাকতে পারে যা alচ্ছিক নয় (কোনও ডিফল্ট মান ছাড়াই)।

তবে পাইথন 2 এর এখনও অনেক বছর ধরে উত্পাদনশীল জীবন রয়েছে, সুতরাং পাইথন 3-তে সরাসরি ভাষায় সমর্থিত গুরুত্বপূর্ণ ডিজাইন আইডিয়াগুলি আপনাকে পাইথন 2 এ প্রয়োগ করতে দেয় সেগুলি ভুলে যাওয়া ভাল নয় !


10
@ অ্যালেক্স মার্তেলি: আমি এমন কোনও উত্তর খুঁজে পাইনি যা দাবি করেছে যে কাওয়ার্স নামধীন যুক্তিগুলির সাথে অভিন্ন, একাকী উন্নততর হোক। তবে পাই 3 কে ভাল বক্তৃতা পরিবর্তিত হয়, সুতরাং +1
বালফা

1
@ অ্যালেক্স মার্তেল্লি: আপনার উত্তরের জন্য অনেক ধন্যবাদ, এটি আমাকে শিখেছে যে পাইথন 3 বাধ্যতামূলক কীওয়ার্ড-যুক্তিগুলির অনুমতি দেয়, যার অভাব প্রায়শই আমার কোড এবং ফাংশনগুলিতে আর্কিটেকচারকে অপ্রত্যাশিত করে তোলে।
ফ্লু

78

আমি এই জাতীয় কিছু প্রস্তাব

def testFunc( **kwargs ):
    options = {
            'option1' : 'default_value1',
            'option2' : 'default_value2',
            'option3' : 'default_value3', }

    options.update(kwargs)
    print options

testFunc( option1='new_value1', option3='new_value3' )
# {'option2': 'default_value2', 'option3': 'new_value3', 'option1': 'new_value1'}

testFunc( option2='new_value2' )
# {'option1': 'default_value1', 'option3': 'default_value3', 'option2': 'new_value2'}

এবং তারপরে মানগুলি যেভাবে চান তা ব্যবহার করুন

dictionaryA.update(dictionaryB)বিষয়বস্তু যোগ dictionaryBকরার dictionaryAকোন ডুপ্লিকেট চাবি মুছে যাওয়ার।


2
ধন্যবাদ @ অভিনবগুপ্ত! ঠিক আমি খুঁজছেন ছিল কি. সবে যুক্ত হয়েছে for key in options: self.__setattr__(key, options[key])এবং আমি যেতে ভাল। :)
propjk007

53

আপনি করতেন

self.attribute = kwargs.pop('name', default_value)

অথবা

self.attribute = kwargs.get('name', default_value)

আপনি যদি ব্যবহার করেন pop, তবে আপনি কোনও বদ্ধমূল মান প্রেরণ করা হয়েছে কিনা তা পরীক্ষা করে দেখতে পারেন এবং যথাযথ ব্যবস্থা নিতে পারেন (যদি থাকে)।


2
"আপনি কি .popকোনও বঞ্চিত মান প্রেরণ করেছেন কিনা তা পরীক্ষা করে দেখার" পরামর্শ দিয়ে আপনি কী বোঝাতে চেয়েছেন তা কি আপনি পরিষ্কার করতে পারেন?
অ্যালান এইচ।

13
@ অ্যালান এইচ .: সমস্ত পপিং শেষ হওয়ার পরে যদি কাওয়ার্গসে কিছু বাকী থাকে, তবে আপনি উত্সাহিত মান পেয়েছেন।
বিনয় সাজিপ

@ ভিনয়েসজিপ: ঠিক আছে, এটি .পপ "বনাম"। গ্রেটের একটি দুর্দান্ত পয়েন্ট, তবে আমি এখনও দেখতে পাচ্ছি না কেন নামকৃত যুক্তিগুলির তুলনায় পপ কেন পছন্দনীয়, এছাড়াও কলারকে অবস্থানগত পরামিতি ব্যবহার না করার জন্য বাধ্য করা উচিত।
MestreLion

1
@ মাস্টারলিয়ন: এটি আপনার এপিআই কতগুলি কীওয়ার্ড আর্গুমেন্টের অনুমতি দেয় তার উপর নির্ভর করে। আমি দাবি করি না যে নামটি দেওয়া যুক্তিগুলির চেয়ে আমার পরামর্শটি ভাল but তবে পাইথন আপনাকে kwargsকোনও কারণে নামহীন যুক্তিগুলি ক্যাপচার করতে দেয় ।
বিনয় সাজিপ

সুতরাং, শুধু পরীক্ষা করা। কী উপস্থিত থাকলে পপ কী কোনও অভিধানের মান দেয় এবং যদি তা default_valueপাস না করে ? এবং সেই চাবিটি পরে সরিয়ে দেয়?
ড্যানিয়েল মুলার

42

** কাওয়ার্গস এবং ডিফল্ট মানগুলি ব্যবহার করা সহজ। কখনও কখনও, তবে, আপনার প্রথম স্থানে ** কাওয়ারগুলি ব্যবহার করা উচিত নয়।

এই ক্ষেত্রে, আমরা সত্যিই ** কোয়ার্গের সর্বোত্তম ব্যবহার করছি না not

class ExampleClass( object ):
    def __init__(self, **kwargs):
        self.val = kwargs.get('val',"default1")
        self.val2 = kwargs.get('val2',"default2")

উপরেরটি "কেন বিরক্ত?" ঘোষণা। এটা যেমন হয়

class ExampleClass( object ):
    def __init__(self, val="default1", val2="default2"):
        self.val = val
        self.val2 = val2

আপনি যখন ** কাওয়ারগুলি ব্যবহার করছেন তখন আপনার অর্থ একটি কীওয়ার্ড কেবল alচ্ছিক নয়, তবে শর্তসাপেক্ষ। সাধারণ ডিফল্ট মানগুলির চেয়ে আরও জটিল নিয়ম রয়েছে।

আপনি যখন ** কাওয়ারগুলি ব্যবহার করছেন, আপনি সাধারণত নীচের মতো আরও কিছু বোঝাতে চান, যেখানে সাধারণ ডিফল্ট প্রয়োগ হয় না।

class ExampleClass( object ):
    def __init__(self, **kwargs):
        self.val = "default1"
        self.val2 = "default2"
        if "val" in kwargs:
            self.val = kwargs["val"]
            self.val2 = 2*self.val
        elif "val2" in kwargs:
            self.val2 = kwargs["val2"]
            self.val = self.val2 / 2
        else:
            raise TypeError( "must provide val= or val2= parameter values" )

আমার সেই ছোট্ট ব্রেইনটিজার পছন্দ! আমি ভাবতে থাকি, "তবে আপনি কেবল পেতে বা পপ করতে পারেন - ওহ, তারা সহ-নির্ভর ..."
ট্রজজার

28

যেহেতু **kwargsযুক্তি সংখ্যা অজানা যখন ব্যবহৃত হয়, কেন এটি করা হচ্ছে না?

class Exampleclass(object):
  def __init__(self, **kwargs):
    for k in kwargs.keys():
       if k in [acceptable_keys_list]:
          self.__setattr__(k, kwargs[k])

হ্যাঁ, এটি মার্জিত এবং শক্তিশালী ... গ্রহণযোগ্য_কিগুলি_লিস্টের চারপাশে বর্গাকার বন্ধনীগুলি সম্পর্কে খুব বেশি নিশ্চিত নন যদিও: আমি এটিকে একটি টিউপল বা একটি তালিকা তৈরি করব এবং তারপরে "যদি" বিবৃতিতে এই বন্ধনীগুলি ফেলে দেব
মাইকে রডেন্ট

: আমি সামান্য ক্ষেত্রেই এই পরিবর্তিত যখন সমস্ত কী আশা করা যায় stackoverflow.com/questions/1098549/...
rebelliard

14

এখানে অন্য পদ্ধতির:

def my_func(arg1, arg2, arg3):
    ... so something ...

kwargs = {'arg1': 'Value One', 'arg2': 'Value Two', 'arg3': 'Value Three'}
# Now you can call the function with kwargs like this:

my_func(**kwargs)

জাজানো সিবিভিতে প্রচুর ব্যবহার করা হয়েছে (উদাঃ get_form_kwargs())। ccbv.co.uk/projects/Django/1.5/django.views.generic.edit/…
ট্রজজার

get_form()পদ্ধতি দেখায় কিভাবে ব্যাপকভাবে অন্য পদ্ধতি থেকে পিছিয়ে দ্বারা শব্দ আর্গুমেন্ট প্রাপ্ত ( get_form_kwargsযেমন উপরে উল্লিখিত)। এটা তোলে ফর্ম instantiates নিম্নরূপ: form_class(**self.get_form_kwargs())
ট্রজজার

এরপরে get_form_kwargs()একটি সাবক্লাস ভিউতে ওভাররাইড করা এবং নির্দিষ্ট যুক্তির উপর ভিত্তি করে কাওয়ার্গগুলি যুক্ত / সরানো সহজ। তবে এটি একটি জ্যাঙ্গো টিউটোরিয়ালের জন্য।
ট্রজজার

12

আমি মনে করি **kwargsডিফল্ট মানগুলির ক্ষেত্রে পাইথনে ব্যবহার করার সঠিক উপায়টি অভিধান পদ্ধতিটি setdefaultনীচের মত ব্যবহার করা:

class ExampleClass:
    def __init__(self, **kwargs):
        kwargs.setdefault('val', value1)
        kwargs.setdefault('val2', value2)

এইভাবে, কোনও ব্যবহারকারী কীওয়ার্ডে 'ভাল' বা 'ভাল 2' পাস argsকরলে সেগুলি ব্যবহার করা হবে; অন্যথায়, সেট করা ডিফল্ট মান ব্যবহার করা হবে।


11

আপনি এই মত কিছু করতে পারে

class ExampleClass:
    def __init__(self, **kwargs):
        arguments = {'val':1, 'val2':2}
        arguments.update(kwargs)
        self.val = arguments['val']
        self.val2 = arguments['val2']

11

সেটট্রটার ব্যবহারের জন্য @ শ্রীদেগদে পরামর্শ অনুসরণ করে :

class ExampleClass(object):
    __acceptable_keys_list = ['foo', 'bar']

    def __init__(self, **kwargs):
        [self.__setattr__(key, kwargs.get(key)) for key in self.__acceptable_keys_list]

ক্লাসটি আমাদের acceptableতালিকার সমস্ত আইটেম রাখবে বলে আশা করা যায় তখন এই রূপটি কার্যকর হয় ।


1
এটি কোনও তালিকা বোধগম্যতার জন্য ব্যবহারের ক্ষেত্রে নয়, আপনার নিজের পদ্ধতিতে লুপের জন্য ব্যবহার করা উচিত।
এটানানি

5

আপনি যদি এটি * আরগ্সের সাথে একত্রিত করতে চান তবে আপনাকে সংজ্ঞাটির শেষে * আরগস এবং ** কাওয়ারগুলি রাখতে হবে।

তাই:

def method(foo, bar=None, *args, **kwargs):
    do_something_with(foo, bar)
    some_other_function(*args, **kwargs)

1

@ অভিনবগুপ্ত এবং @ স্টিফ ব্যবহার করার পরামর্শ দিয়েছিল update(), যেগুলি বড় আর্গুমেন্ট তালিকাগুলি প্রক্রিয়াকরণের জন্য আমি খুব সহায়ক বলে মনে করেছি:

args.update(kwargs)

যদি আমরা এটি পরীক্ষা করতে চাই যে ব্যবহারকারী কোনও উত্কৃষ্ট / অসমর্থিত তর্কটি পাস করেনি? @ ভিনয়েসাজিপ নির্দেশ করেছেন যে pop()আর্গুমেন্টগুলির তালিকাটি পুনরাবৃত্তিভাবে প্রক্রিয়া করতে ব্যবহৃত হতে পারে। তারপরে, যে কোনও বাকী যুক্তি উত্সাহিত হয়। খুশী হলাম।

এটি করার আরও একটি সম্ভাব্য উপায় এখানে ব্যবহারের সহজ বাক্য গঠন রাখে update():

# kwargs = dictionary of user-supplied arguments
# args = dictionary containing default arguments

# Check that user hasn't given spurious arguments
unknown_args = user_args.keys() - default_args.keys()
if unknown_args:
    raise TypeError('Unknown arguments: {}'.format(unknown_args))

# Update args to contain user-supplied arguments
args.update(kwargs)

unknown_argsএটি setআর্গুমেন্টের নামযুক্ত যা ডিফল্টগুলিতে ঘটে না।


0

অজানা বা একাধিক যুক্তি প্রক্রিয়াকরণের জন্য আরেকটি সহজ সমাধান হতে পারে:

class ExampleClass(object):

    def __init__(self, x, y, **kwargs):
      self.x = x
      self.y = y
      self.attributes = kwargs

    def SomeFunction(self):
      if 'something' in self.attributes:
        dosomething()

0

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

class Person(object):
listed_keys = ['name', 'age']

def __init__(self, **kwargs):
    _dict = {}
    # Set default values for listed keys
    for item in self.listed_keys: 
        _dict[item] = 'default'
    # Update the dictionary with all kwargs
    _dict.update(kwargs)

    # Have the keys of kwargs as instance attributes
    self.__dict__.update(_dict)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.