मैं एक डेकोरेटर पर काम कर रहा हूं जो डेकोरेटेड मेथड के पहले तर्क पर एक फंक्शन चलाता है जो self नहीं है। इसे पूरा करने के लिए, मैं वर्तमान में मूल रूप से समान कोड वाले दो सज्जाकारों का उपयोग कर रहा हूं। अंतर केवल इतना है कि किसी के पास एक ऐसा कार्य होता है जिसमें पहले तर्क से पहले स्वयं होता है।

import functools

def wrap(function):
    @functools.wraps(function)
    def wrapper(first_argument, *args, **kwargs):
        someFuntion(first_argument)
        return function(first_argument, *args, **kwargs)
    return wrapper

def wrapClass(function):
    @functools.wraps(function)
    def wrapper(self, first_argument, *args, **kwargs):
        someFuntion(first_argument)
        return function(self, first_argument, *args, **kwargs)
    return wrapper

मैं इस तरह के प्रारूप में दो सज्जाकारों को एक में जोड़ना चाहता हूं:

import functools

def wrap(function):
    if isPartOfClass(function):
        @functools.wraps(function)
        def wrapper(self, first_argument, *args, **kwargs):
            someFuntion(first_argument)
            return function(self, first_argument, *args, **kwargs)
    else:
        @functools.wraps(function)
        def wrapper(first_argument, *args, **kwargs):
            someFuntion(first_argument)
            return function(first_argument, *args, **kwargs)
    return wrapper

पायथन 2 में मैं केवल यह पता लगाने में सक्षम हुआ करता था कि क्या फ़ंक्शन एक अनबाउंड विधि है। हालाँकि, मुझे पता है कि उस अवधारणा को पायथन 3 में हटा दिया गया था।

मैं पहले से ही कई पहचान विधियों के साथ आया हूं जो काम नहीं करेंगे।

  1. मैं पहले जांच सकता था कि क्या पहला तर्क self कहा जाता है, लेकिन यह आवश्यक नाम नहीं है।
  2. मैं यह पता लगाने की कोशिश कर सकता हूं कि फ़ंक्शन में 1 (नियमित) या 2 (वर्ग) तर्क हैं, लेकिन नियमित फ़ंक्शन में 1 से अधिक तर्क हो सकते हैं। तर्कों की संख्या के बावजूद, मुझे केवल पहले तर्क की परवाह है जो स्वयं नहीं है।
  3. मैं प्रकार के आधार पर पहले तर्क का पता लगाने का प्रयास कर सकता था, लेकिन इस बात की कोई गारंटी नहीं है कि यह किस प्रकार का होगा।

क्या मेरे लिए यह पता लगाने का कोई व्यावहारिक तरीका है, या क्या मैं दो सज्जाकारों के साथ फंसने जा रहा हूं?

1
The Elemental of Destruction 26 नवम्बर 2020, 16:36

1 उत्तर

सबसे बढ़िया उत्तर

क्या आपके उपयोगकेस के लिए __qualname__ की जांच करेंगे?

In [19]: class Foo: 
    ...:     def __init__(self, x): 
    ...:         self.x = x 
    ...:     def __str__(self): return "foo" 
    ...:     def __repr__(self): return f"Foo({self.x})" 
    ...:     def bar(self): return 1 
    ...:                                                                                                                                                                                                                                                      

In [20]: b = Foo.bar                                                                                                                                                                                                                                          

In [21]: b                                                                                                                                                                                                                                                    
Out[21]: <function __main__.Foo.bar(self)>

In [22]: b.__qualname__                                                                                                                                                                                                                                       
Out[22]: 'Foo.bar'

__qualname__ में . की उपस्थिति एक कक्षा में एक विधि के लिए एक मृत उपहार होना चाहिए। अन्य कार्यों में वह नहीं है:

In [24]: print.__qualname__                                                                                                                                                                                                                                   
Out[24]: 'print'

गैर-बिलिन फ़ंक्शन के लिए

In [25]: def foo(x): return ''                                                                                                                                                                                                                                

In [26]: foo.__qualname__                                                                                                                                                                                                                                     
Out[26]: 'foo'

आयातित फ़ंक्शन के लिए:

In [23]: inspect.getargs.__qualname__                                                                                                                                                                                                                         
Out[23]: 'getargs'
2
inspectorG4dget 26 नवम्बर 2020, 13:46