স্বয়ংক্রিয়ভাবে উদাহরণের ভেরিয়েবলগুলি আরম্ভ করবেন?


90

আমার কাছে অজগর শ্রেণিটি দেখতে এরকম দেখাচ্ছে:

class Process:
    def __init__(self, PID, PPID, cmd, FDs, reachable, user):

অনুসরণ করেছে:

        self.PID=PID
        self.PPID=PPID
        self.cmd=cmd
        ...

C ++ এর প্রারম্ভিক তালিকার মতো এই ইনস্ট্যান্স ভেরিয়েবলগুলিকে অটোয়াইটাইজ করার কোনও উপায় আছে কি? এটি প্রচুর রিলান্ড্যান্ট কোডটি ছাড়বে।


4
autoassignঅ্যাক্টিস্টেট রেসিপি এবং এখানে একটি বিকল্প autoargsবাস্তবায়ন সম্পর্কেও আলোচনা দেখুন : পাইথনে স্বয়ংক্রিয় বৈশিষ্ট্য কার্যনির্বাহনের সর্বোত্তম উপায় কোনটি এবং এটি কী ভাল ধারণা? - স্ট্যাক ওভারফ্লো
নীলাম্যাকবি

উত্তর:


104

আপনি একটি সাজসজ্জার ব্যবহার করতে পারেন:

from functools import wraps
import inspect

def initializer(func):
    """
    Automatically assigns the parameters.

    >>> class process:
    ...     @initializer
    ...     def __init__(self, cmd, reachable=False, user='root'):
    ...         pass
    >>> p = process('halt', True)
    >>> p.cmd, p.reachable, p.user
    ('halt', True, 'root')
    """
    names, varargs, keywords, defaults = inspect.getargspec(func)

    @wraps(func)
    def wrapper(self, *args, **kargs):
        for name, arg in list(zip(names[1:], args)) + list(kargs.items()):
            setattr(self, name, arg)

        for name, default in zip(reversed(names), reversed(defaults)):
            if not hasattr(self, name):
                setattr(self, name, default)

        func(self, *args, **kargs)

    return wrapper

__init__পদ্ধতিটি সাজানোর জন্য এটি ব্যবহার করুন :

class process:
    @initializer
    def __init__(self, PID, PPID, cmd, FDs, reachable, user):
        pass

আউটপুট:

>>> c = process(1, 2, 3, 4, 5, 6)
>>> c.PID
1
>>> dir(c)
['FDs', 'PID', 'PPID', '__doc__', '__init__', '__module__', 'cmd', 'reachable', 'user'

4
এটি কাজ করে এবং প্রশ্নের উত্তর দেয় তাই আমি ভোট দিয়েছি। তবে আমি ফেরডিড্যান্ড বেয়ারের উত্তরটি রেখেছি: "স্পষ্ট বর্ণের চেয়ে সুস্পষ্ট"
লুকাস গ্যাব্রিয়েল সানচেজ

14
+1 দুর্দান্ত উত্তরের জন্য যা আমার সমস্যার সমাধান করেছে। তবে এটি কি ভাষার মূল কার্যকারিতা হওয়া উচিত না? আপনি কি মনে করেন এটি একটি পিইপি লিখতে মূল্যবান?
আদম মতান

4
এটি সত্যিই ভাল উত্তর - এটি সরাসরি আমার সরঞ্জামবক্সে চলে গেছে।
মাইকেল ভ্যান ডের ওয়েস্টুইজেন

4
@ নাদিয়াআলরামলি আমার মনে হয় কোডটিতে একটি ছোট বাগ আছে। এখানে gist.github.com/pmav99/137dbf4681be9a58de74 (original.py) দেখুন
pmav99

4
বর্তমান উদাহরণটিতে একটি বাগ রয়েছে এবং স্বাক্ষরটিতে ডিফল্ট যুক্তি অন্তর্ভুক্ত না হলে কাজ করবে না। নাম এবং ডিফল্ট কোনওটি নয় তা নিশ্চিত করার জন্য আপনাকে একটি চেক অন্তর্ভুক্ত করতে হবে।

36

আপনি যদি পাইথন ২.6 বা ততোধিক উচ্চতর ব্যবহার করে থাকেন তবে আপনি সংগ্রহগুলি.নেমটুপল ব্যবহার করতে পারেন :

>>> from collections import namedtuple
>>> Process = namedtuple('Process', 'PID PPID cmd')
>>> proc = Process(1, 2, 3)
>>> proc.PID
1
>>> proc.PPID
2

এটি উপযুক্ত যখন বিশেষত যখন আপনার শ্রেণিটি সত্যিকারের একটি বড় ব্যাগ থাকে।


4
"এটি যথাযথভাবে বিশেষত যখন আপনার ক্লাসটি সত্যিকারের একটি বড় ব্যাগ হয়" " এই জাতীয়
দৃশ্যে

35

পাইথন ৩.7++ এর জন্য আপনি একটি ডেটা ক্লাস ব্যবহার করতে পারেন যা আপনি যা চান তা করার জন্য খুব অজগর এবং রক্ষণাবেক্ষণের উপায়।

এটি আপনাকে আপনার শ্রেণীর জন্য ক্ষেত্রগুলি নির্ধারণ করতে দেয় , যা আপনার স্বয়ংক্রিয়ভাবে সূচনাপ্রাপ্ত দৃষ্টান্তের ভেরিয়েবল।

এটি দেখতে এমন কিছু লাগবে:

@dataclass
class Process:
    PID: int
    PPID: int
    cmd: str
    ...

__init__পদ্ধতি ইতিমধ্যে আপনার বর্গ মধ্যে হতে হবে।

নোট করুন যে এখানে টাইপ হিন্টিং প্রয়োজন , সেই কারণেই আমি ব্যবহার করেছি intএবং strউদাহরণে। আপনি যদি আপনার ক্ষেত্রের প্রকারটি জানেন না, আপনি মডিউল থেকে যে typingকোনওটি ব্যবহার করতে পারেন ।

প্রস্তাবিত সমাধানগুলির তুলনায় ডেটা ক্লাসের অনেক সুবিধা রয়েছে:

  • এটি সুস্পষ্ট : সমস্ত ক্ষেত্র দৃশ্যমান, যা পাইথনের জেনকে সম্মান করে এবং এটি পাঠযোগ্য এবং রক্ষণাবেক্ষণযোগ্য করে তোলে। এর ব্যবহারের সাথে তুলনা করুন **kwargs
  • এটির পদ্ধতি থাকতে পারে । ঠিক অন্য শ্রেণীর মতো।
  • এটি আপনাকে পদ্ধতিটি __init__ব্যবহার করে স্বয়ংক্রিয়র বাইরে যেতে দেয় __post_init__

সম্পাদনা: নামডটপলস ব্যবহার এড়ানোর কারণ

কেউ কেউ namedtupleএই ক্ষেত্রে ব্যবহারের পরামর্শ দিচ্ছেন , তবে নেমটুপলসের কিছু আচরণ রয়েছে যা পাইথন ক্লাস থেকে পৃথক, যা প্রথমে প্রকৃতপক্ষে স্পষ্ট নয় এবং সুপরিচিত হওয়া উচিত:

১. নামভুক্ত টিপলস অপরিবর্তনীয়

অপরিচ্ছন্নতা দরকারী হতে পারে, তবে আপনার উদাহরণগুলির জন্য এটি যা চান তা নয়। DataClasses এছাড়াও একরকম অপরিবর্তনীয় যদি আপনি যুক্তি ব্যবহার হতে পারে frozen=Trueউপর @dataclassপ্রসাধক।

২.নামডটুপলস টিপলের __eq__মতো আচরণ করে

পাইথনে, SomeNamedTuple(a=1, b=2) == AnotherNamedTuple(c=1, d=2)হয় True! __eq__তুলনামূলকভাবে ব্যবহৃত নেমডটপলের ফাংশনটি কেবল তাদের শ্রেণি বা ক্ষেত্রের নাম নয় তুলনামূলক দৃষ্টান্তগুলিতে সেই মানগুলির মান এবং অবস্থান বিবেচনা করে।


ক্লাসের উদ্দেশ্য ডেটা সঞ্চয় করা হলে এটি ব্যবহার করা উচিত।
জেসি রোকামন্ডে

অথবা ডেটা সঞ্চয় করার আশেপাশে বিকাশ করা।
জেসি রোকামন্ডে

4
আপনি কী ব্যাখ্যা করতে পারেন যে কেন ডেটাগ্লাস কেবল অন্য শ্রেণীর আচরণের পরিবর্তে ডেটা সংরক্ষণ করে এমন ক্লাসগুলির জন্য ব্যবহার করা উচিত? এর যথাযথ ব্যবহারের কেসগুলি আরও ভালভাবে বোঝার জন্য আমি এটির জন্য সম্পূর্ণ নতুন একটি এসও পোস্ট তৈরি করতে পারি। ধন্যবাদ
ওয়াহিদ পজিরান্দিহ

Data Classes can be thought of as "mutable namedtuples with defaults". - পিইপি 557
আফিউলই

26

পাইথনের জেনটি উদ্ধৃত করে ,

সুস্পষ্ট বর্ণিত চেয়ে ভাল।


10
একটি সূচনা তালিকা ঘোষণা যথেষ্ট সুস্পষ্ট হবে না?
আদম মতান

আমি অনুমান করি. তবে ভাষার মতো কিছু যুক্ত করার কোনও কারণ আমি দেখছি না। আমি দৃশ্যের পিছনে একরকম ডেকরেটার-ম্যাজিকের চেয়ে একাধিক অ্যাসাইনমেন্ট স্টেটমেন্ট পছন্দ করি।
ফার্ডিনান্ড বায়ার

30
@ ফারডিনান্দ, আমি সম্মত হই যে ভাষাতে এমন কিছু পাওয়া উচিত যা নির্দ্বিধায় স্টাডলিবের মধ্যে থাকতে পারে তবে এটি স্টাডলিবের মধ্যে হওয়া উচিত, কারণ "কুশ্রীর চেয়ে সুন্দর সুন্দর" অগ্রাধিকার গ্রহণ করে এবং অনেক পুনরাবৃত্তির কাজ অশুভ (পুনরাবৃত্তি যে কোনও ফর্ম হিসাবে)।
অ্যালেক্স মার্টেলি

ঠিক আছে, পাল্টাতে: DWIM> DWIS
টেরেন্স ব্র্যানন

আমি সম্মত হব যে অ্যাসাইনমেন্টের তালিকার চেয়ে সাজসজ্জারটি আরও সুন্দর তবে পাইচার্ম এটি না বুঝে এটি আরও সুশৃঙ্খল করে তোলে :-(
user110954

23

আর একটি জিনিস যা আপনি করতে পারেন:

class X(object):
    def __init__(self, a,b,c,d):
        vars = locals() # dict of local names
        self.__dict__.update(vars) # __dict__ holds and object's attributes
        del self.__dict__["self"] # don't need `self`

তবে আমি কেবলমাত্র এটির বানান ছাড়াও কেবলমাত্র সমাধানটিই সুপারিশ করব, এটি হল "আপনার সম্পাদকটিতে একটি ম্যাক্রো তৈরি করুন" ;-পি


4
'স্ব' মুছে ফেলার জন্য ভাল ধরা।
মাইকেল 25

15

আপনি কীওয়ার্ড আর্গুমেন্টগুলির সাহায্যে এটি সহজেই করতে পারতেন, যেমন:

>>> class D:
    def __init__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

>>> D(test='d').test
'd'

অবস্থানগত আর্গুমেন্টগুলির জন্য অনুরূপ বাস্তবায়ন হবে:

>> class C:
    def __init__(self, *args):
        self.t, self.d = args


>>> C('abc', 'def').t
'abc'
>>> C('abc', 'def').d
'def'

আমার কাছে যা আপনার সমস্যার সমাধান বলে মনে হচ্ছে না।


4
আমি পছন্দ করি এমন আরও একটি পরিবর্তন হ'লself.__dict__.update( **kwargs )
S.Lott

স্থানীয়দের পাশাপাশি ব্যবহার করতে পারেন () এবং সাধারণ আর্গুমেন্ট রাখুন।
mk12

7

নাদিয়ার সমাধানটি আরও ভাল এবং আরও শক্তিশালী, তবে আমি এটিও আকর্ষণীয় বলে মনে করি:

def constructor(*arg_names):
  def __init__(self, *args):
    for name, val in zip(arg_names, args):
      self.__setattr__(name, val)
  return __init__


class MyClass(object):
  __init__ = constructor("var1", "var2", "var3")


>>> c = MyClass("fish", "cheese", "beans")
>>> c.var2
"cheese"

5

আমার একই উদ্দেশ্যে কিছু প্রয়োজন ছিল, তবে বিদ্যমান উত্তরগুলির মধ্যে আমার পরীক্ষিত সমস্ত মামলার জুড়েই কোনও উত্তর নেই। নাদিয়ার উত্তরটি আমি যা খুঁজছিলাম তার নিকটতম ছিল, তাই আমি তার কোডটি একটি বেস হিসাবে শুরু করেছি।

নীচের সাজসজ্জাটি যুক্তিযুক্ত সমস্ত বৈধ সংমিশ্রণের সাথে কাজ করে:

Positional                                          __init__(self, a, b                )
Keyword                                             __init__(self, a=None, b=None      )
Positional + Keyword                                __init__(self, a, b, c=None, d=None)
Variable Positional                                 __init__(self, *a                  )
Variable Positional + Keyword                       __init__(self, *a, b=None          )
Variable Positional + Variable Keyword              __init__(self, *a, **kwargs        )
Positional + Variable Positional + Keyword          __init__(self, a, *b, c=None       )
Positional + Variable Positional + Variable Keyword __init__(self, a, *b, **kwargs     )
Keyword Only                                        __init__(self, *, a=None           )
Positional + Keyword Only                           __init__(self, a, *, b=None        )

এটি শ্রেণীর দৃষ্টান্তগুলিতে বরাদ্দ করা হবে না এমন-প্রাইভেট ভেরিয়েবলগুলির _জন্য অনুমতি দেওয়ার জন্য স্ট্যান্ডার্ড- প্রিফিক্স কনভেনশনটিও প্রয়োগ করে __init__


###  StdLib  ###
from functools import wraps
import inspect


###########################################################################################################################
#//////|   Decorator   |//////////////////////////////////////////////////////////////////////////////////////////////////#
###########################################################################################################################

def auto_assign_arguments(function):

  @wraps(function)
  def wrapped(self, *args, **kwargs):
    _assign_args(self, list(args), kwargs, function)
    function(self, *args, **kwargs)

  return wrapped


###########################################################################################################################
#//////|   Utils   |//////////////////////////////////////////////////////////////////////////////////////////////////////#
###########################################################################################################################

def _assign_args(instance, args, kwargs, function):

  def set_attribute(instance, parameter, default_arg):
    if not(parameter.startswith("_")):
      setattr(instance, parameter, default_arg)

  def assign_keyword_defaults(parameters, defaults):
    for parameter, default_arg in zip(reversed(parameters), reversed(defaults)):
      set_attribute(instance, parameter, default_arg)

  def assign_positional_args(parameters, args):
    for parameter, arg in zip(parameters, args.copy()):
      set_attribute(instance, parameter, arg)
      args.remove(arg)

  def assign_keyword_args(kwargs):
    for parameter, arg in kwargs.items():
      set_attribute(instance, parameter, arg)
  def assign_keyword_only_defaults(defaults):
    return assign_keyword_args(defaults)

  def assign_variable_args(parameter, args):
    set_attribute(instance, parameter, args)

  POSITIONAL_PARAMS, VARIABLE_PARAM, _, KEYWORD_DEFAULTS, _, KEYWORD_ONLY_DEFAULTS, _ = inspect.getfullargspec(function)
  POSITIONAL_PARAMS = POSITIONAL_PARAMS[1:] # remove 'self'

  if(KEYWORD_DEFAULTS     ): assign_keyword_defaults     (parameters=POSITIONAL_PARAMS,  defaults=KEYWORD_DEFAULTS)
  if(KEYWORD_ONLY_DEFAULTS): assign_keyword_only_defaults(defaults=KEYWORD_ONLY_DEFAULTS                          )
  if(args                 ): assign_positional_args      (parameters=POSITIONAL_PARAMS,  args=args                )
  if(kwargs               ): assign_keyword_args         (kwargs=kwargs                                           )
  if(VARIABLE_PARAM       ): assign_variable_args        (parameter=VARIABLE_PARAM,      args=args                )


###########################################################################################################################$#//////|   Tests   |//////////////////////////////////////////////////////////////////////////////////////////////////////#$###########################################################################################################################$$if __name__ == "__main__":$$#######|   Positional   |##################################################################################################$$  class T:$    @auto_assign_arguments$    def __init__(self, a, b):$      pass$$  t = T(1, 2)$  assert (t.a == 1) and (t.b == 2)$$#######|   Keyword   |#####################################################################################################$$  class T:$    @auto_assign_arguments$    def __init__(self, a="KW_DEFAULT_1", b="KW_DEFAULT_2"):$      pass$$  t = T(a="kw_arg_1", b="kw_arg_2")$  assert (t.a == "kw_arg_1") and (t.b == "kw_arg_2")$$#######|   Positional + Keyword   |########################################################################################$$  class T:$    @auto_assign_arguments$    def __init__(self, a, b, c="KW_DEFAULT_1", d="KW_DEFAULT_2"):$      pass$$  t = T(1, 2)$  assert (t.a == 1) and (t.b == 2) and (t.c == "KW_DEFAULT_1") and (t.d == "KW_DEFAULT_2")$$  t = T(1, 2, c="kw_arg_1")$  assert (t.a == 1) and (t.b == 2) and (t.c == "kw_arg_1") and (t.d == "KW_DEFAULT_2")$$  t = T(1, 2, d="kw_arg_2")$  assert (t.a == 1) and (t.b == 2) and (t.c == "KW_DEFAULT_1") and (t.d == "kw_arg_2")$$#######|   Variable Positional   |#########################################################################################$$  class T:$    @auto_assign_arguments$    def __init__(self, *a):$      pass$$  t = T(1, 2, 3)$  assert (t.a == [1, 2, 3])$$#######|   Variable Positional + Keyword   |###############################################################################$$  class T:$    @auto_assign_arguments$    def __init__(self, *a, b="KW_DEFAULT_1"):$      pass$$  t = T(1, 2, 3)$  assert (t.a == [1, 2, 3]) and (t.b == "KW_DEFAULT_1")$$  t = T(1, 2, 3, b="kw_arg_1")$  assert (t.a == [1, 2, 3]) and (t.b == "kw_arg_1")$$#######|   Variable Positional + Variable Keyword   |######################################################################$$  class T:$    @auto_assign_arguments$    def __init__(self, *a, **kwargs):$      pass$$  t = T(1, 2, 3, b="kw_arg_1", c="kw_arg_2")$  assert (t.a == [1, 2, 3]) and (t.b == "kw_arg_1") and (t.c == "kw_arg_2")$$#######|   Positional + Variable Positional + Keyword   |##################################################################$$  class T:$    @auto_assign_arguments$    def __init__(self, a, *b, c="KW_DEFAULT_1"):$      pass$$  t = T(1, 2, 3, c="kw_arg_1")$  assert (t.a == 1) and (t.b == [2, 3]) and (t.c == "kw_arg_1")$$#######|   Positional + Variable Positional + Variable Keyword   |#########################################################$$  class T:$    @auto_assign_arguments$    def __init__(self, a, *b, **kwargs):$      pass$$  t = T(1, 2, 3, c="kw_arg_1", d="kw_arg_2")$  assert (t.a == 1) and (t.b == [2, 3]) and (t.c == "kw_arg_1") and (t.d == "kw_arg_2")$$#######|   Keyword Only   |################################################################################################$$  class T:$    @auto_assign_arguments$    def __init__(self, *, a="KW_DEFAULT_1"):$      pass$$  t = T(a="kw_arg_1")$  assert (t.a == "kw_arg_1")$$#######|   Positional + Keyword Only   |###################################################################################$$  class T:$    @auto_assign_arguments$    def __init__(self, a, *, b="KW_DEFAULT_1"):$      pass$$  t = T(1)$  assert (t.a == 1) and (t.b == "KW_DEFAULT_1")$$  t = T(1, b="kw_arg_1")$  assert (t.a == 1) and (t.b == "kw_arg_1")$$#######|   Private __init__ Variables (underscored)   |####################################################################$$  class T:$    @auto_assign_arguments$    def __init__(self, a, b, _c):$      pass$$  t = T(1, 2, 3)$  assert hasattr(t, "a") and hasattr(t, "b") and not(hasattr(t, "_c"))

বিঃদ্রঃ:

আমি পরীক্ষাগুলি অন্তর্ভুক্ত করেছি, কিন্তু সংক্ষিপ্ততার জন্য এগুলি শেষ লাইনে ( 58 ) ভেঙে ফেলেছি । আপনি পরীক্ষাগুলি প্রসারিত করতে পারেন, যা সম্ভাব্য ব্যবহারের সমস্ত ক্ষেত্রেই একটি নতুন লাইন দিয়ে find/replaceসমস্ত $অক্ষরকে বিস্তৃত করে দেয় detail


3

ভেরিয়েবল আরম্ভ করার প্রয়োজন হতে পারে না, কারণ স্থানীয় () এর মধ্যে ইতিমধ্যে মান রয়েছে!

ক্লাস ডামি (অবজেক্ট):

def __init__(self, a, b, default='Fred'):
    self.params = {k:v for k,v in locals().items() if k != 'self'}

d = ডামি (2, 3)

d.params

a 'এ': 2, 'বি': 3, 'ডিফল্ট': 'ফ্রেড'}

ডি.প্যারামস ['বি']

অবশ্যই, একটি শ্রেণীর মধ্যে কেউ নিজের.প্রেম ব্যবহার করতে পারে


এটা একটা চমৎকার এবং মূল পদ্ধতির, কিন্তু d['b']পাইথন এর লেখা আছে Lingua Franca যখন d.params['b']কোড পাঠকদের জন্য বিভ্রান্তির কারণ হবে।
আদম মতান

3

getargspecপাইথন ৩.৫ থেকে অবহেলিত হওয়ার সাথে সাথেই এখানে সমাধানটি এখানে ব্যবহার করুন inspect.signature:

from inspect import signature, Parameter
import functools


def auto_assign(func):
    # Signature:
    sig = signature(func)
    for name, param in sig.parameters.items():
        if param.kind in (Parameter.VAR_POSITIONAL, Parameter.VAR_KEYWORD):
            raise RuntimeError('Unable to auto assign if *args or **kwargs in signature.')
    # Wrapper:
    @functools.wraps(func)
    def wrapper(self, *args, **kwargs):
        for i, (name, param) in enumerate(sig.parameters.items()):
            # Skip 'self' param:
            if i == 0: continue
            # Search value in args, kwargs or defaults:
            if i - 1 < len(args):
                val = args[i - 1]
            elif name in kwargs:
                val = kwargs[name]
            else:
                val = param.default
            setattr(self, name, val)
        func(self, *args, **kwargs)
    return wrapper

কাজ করে কিনা তা পরীক্ষা করুন:

class Foo(object):
    @auto_assign
    def __init__(self, a, b, c=None, d=None, e=3):
        pass

f = Foo(1, 2, d="a")
assert f.a == 1
assert f.b == 2
assert f.c is None
assert f.d == "a"
assert f.e == 3

print("Ok")

2

পাইথন ৩.৩++ এর জন্য:

from functools import wraps
from inspect import Parameter, signature


def instance_variables(f):
    sig = signature(f)
    @wraps(f)
    def wrapper(self, *args, **kwargs):
        values = sig.bind(self, *args, **kwargs)
        for k, p in sig.parameters.items():
            if k != 'self':
                if k in values.arguments:
                    val = values.arguments[k]
                    if p.kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY):
                        setattr(self, k, val)
                    elif p.kind == Parameter.VAR_KEYWORD:
                        for k, v in values.arguments[k].items():
                            setattr(self, k, v) 
                else:
                    setattr(self, k, p.default) 
    return wrapper

class Point(object):
    @instance_variables 
    def __init__(self, x, y, z=1, *, m='meh', **kwargs):
        pass

ডেমো:

>>> p = Point('foo', 'bar', r=100, u=200)
>>> p.x, p.y, p.z, p.m, p.r, p.u
('foo', 'bar', 1, 'meh', 100, 200)

পাইথন 2 এবং 3 ফ্রেম ব্যবহার করে উভয়ের জন্য একটি অ-সজ্জনকারী পদ্ধতির:

import inspect


def populate_self(self):
    frame = inspect.getouterframes(inspect.currentframe())[1][0]
    for k, v in frame.f_locals.items():
        if k != 'self':
            setattr(self, k, v)


class Point(object):
    def __init__(self, x, y):
        populate_self(self)

ডেমো:

>>> p = Point('foo', 'bar')
>>> p.x
'foo'
>>> p.y
'bar'

1

nu11ptr একটি ছোট মডিউল তৈরি করেছে, পাইআইন্সট্যান্স ভারস , যা এতে ফাংশন ডেকোরেটর হিসাবে এই কার্যকারিতাটি অন্তর্ভুক্ত করে। মডিউলটির README তে বলা হয়েছে যে " [...] সম্পাদনা এখন সিপিথনের অধীনে সুস্পষ্ট সূচনার চেয়ে 30-40% খারাপ "।

ব্যবহারের উদাহরণ, মডিউলটির ডকুমেন্টেশন থেকে সরাসরি তুলে নেওয়া :

>>> from instancevars import *
>>> class TestMe(object):
...     @instancevars(omit=['arg2_'])
...     def __init__(self, _arg1, arg2_, arg3='test'):
...             self.arg2 = arg2_ + 1
...
>>> testme = TestMe(1, 2)
>>> testme._arg1
1
>>> testme.arg2_
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'TestMe' object has no attribute 'arg2_'
>>> testme.arg2
3
>>> testme.arg3
'test'

0

হতে পারে এটি একটি বদ্ধ প্রশ্ন, তবে আপনি এটি সম্পর্কে কী ভাবছেন তা জানতে আমি আমার সমাধানটি প্রস্তাব করতে চাই। আমি একটি প্রসাধক প্রযোজ্য যা ক্লাসের অধীনে একটি ক্লাস ব্যবহার করেছেন Init পদ্ধতি

import inspect

class AutoInit(type):
    def __new__(meta, classname, supers, classdict):
        classdict['__init__'] = wrapper(classdict['__init__'])
        return type.__new__(meta, classname, supers, classdict)

def wrapper(old_init):
    def autoinit(*args):
        formals = inspect.getfullargspec(old_init).args
        for name, value in zip(formals[1:], args[1:]):
            setattr(args[0], name, value)
    return autoinit



আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.