পাইথন ফাংশন বৈশিষ্ট্য - ব্যবহার এবং আপত্তি [বন্ধ]


195

অনেকেই এই বৈশিষ্ট্য সম্পর্কে সচেতন নন তবে পাইথনের ফাংশনগুলি (এবং পদ্ধতিগুলি) এর বৈশিষ্ট্য থাকতে পারে । দেখ:

>>> def foo(x):
...     pass
...     
>>> foo.score = 10
>>> dir(foo)
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name', 'score']
>>> foo.score
10
>>> foo.score += 1
>>> foo.score
11

পাইথনে এই বৈশিষ্ট্যটির সম্ভাব্য ব্যবহার এবং অপব্যবহারগুলি কী কী? এক ভাল ব্যবহার আমি সচেতন আছি অটলভাবে কাজ করা docstring একটি পদ্ধতি সঙ্গে একটি বাক্য গঠন নিয়ম শরীক করা 'র ব্যবহার। কিন্তু কাস্টম বৈশিষ্ট্য সম্পর্কে কি? সেগুলি ব্যবহার করার কোনও ভাল কারণ আছে?


3
পরীক্ষা করে দেখুন PEP 232
ব্যবহারকারী140352

2
এটা কি খুব অবাক? সাধারণভাবে, পাইথন অবজেক্টগুলি অ্যাড-হক বৈশিষ্ট্যগুলি সমর্থন করে। অবশ্যই, কিছু না বিশেষত বিল্টিন টাইপযুক্ত যারা না। আমার কাছে, যারা এটি সমর্থন করে না তাদেরকে ব্যতিক্রম বলে মনে হয়, নিয়ম নয়।
অ্যালিউরকোড


2
@ গ্রিজেশচৌহান এই ডক্সগুলি দেখে আমি এই প্রশ্নে এসেছি!
আলেকজান্ডার সুর্যাপেল

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

উত্তর:


153

আমি সাধারণত টীকাগুলির জন্য সঞ্চয় হিসাবে ফাংশন বৈশিষ্ট্যগুলি ব্যবহার করি। ধরুন আমি সি # এর স্টাইলে লিখতে চাই (এটি নির্দিষ্ট করে যে একটি নির্দিষ্ট পদ্ধতি ওয়েব পরিষেবা ইন্টারফেসের অংশ হওয়া উচিত)

class Foo(WebService):
    @webmethod
    def bar(self, arg1, arg2):
         ...

তাহলে আমি সংজ্ঞা দিতে পারি

def webmethod(func):
    func.is_webmethod = True
    return func

তারপরে, যখন কোনও ওয়েব সার্ভিস কল আসে, আমি পদ্ধতিটি সন্ধান করি, অন্তর্নিহিত ফাংশনটিতে is_webmethod বৈশিষ্ট্য আছে (আসল মানটি অপ্রাসঙ্গিক) কিনা তা পরীক্ষা করে দেখি এবং যদি পদ্ধতিটি অনুপস্থিত থাকে বা ওয়েবে কল করার উদ্দেশ্যে নয় তবে পরিষেবাটি প্রত্যাখ্যান করি।


2
আপনি কি মনে করেন এটির নিচের দিক রয়েছে? উদাহরণস্বরূপ, যদি দুটি গ্রন্থাগার একই অ্যাড-হক বৈশিষ্ট্যটি লেখার চেষ্টা করে?
অ্যালিওরকোড

18
আমি ঠিক এটি করার কথা ভাবছিলাম। তখন আমি নিজেকে থামিয়ে দিলাম। "এটা কি একটি খারাপ ধারণা?" আমি আশ্চর্যান্বিত. তারপরে, আমি ঘোরাফেরা করে এসও এর কাছে গেলাম। চারপাশে কিছুটা ধমক দেওয়ার পরে আমি এই প্রশ্ন / উত্তরটি পেয়েছি। এটি একটি ভাল ধারণা কিনা তা এখনও নিশ্চিত নয়।
অ্যালিউরকোড

7
এটি অবশ্যই সমস্ত উত্তরের ফাংশন বৈশিষ্ট্যের সর্বাধিক আইনী ব্যবহার (নভেম্বর, ২০১২ হিসাবে)। বেশিরভাগ (সমস্ত না থাকলে) অন্যান্য উত্তরগুলি গ্লোবাল ভেরিয়েবলের প্রতিস্থাপন হিসাবে ফাংশন বৈশিষ্ট্যগুলি ব্যবহার করে; তবে, তারা বিশ্বব্যাপী রাষ্ট্র থেকে মুক্তি পান না, যা বৈশ্বিক ভেরিয়েবলগুলির সাথে ঠিক সমস্যা। এটি ভিন্ন, কারণ একবার মান সেট করা থাকলে, এটি পরিবর্তন হয় না; এটা ধ্রুবক। এর একটি দুর্দান্ত পরিণতি হ'ল আপনি সিঙ্ক্রোনাইজেশন সমস্যাগুলিতে চলে না যা গ্লোবাল ভেরিয়েবলের সহজাত। হ্যাঁ, আপনি নিজের সিঙ্ক্রোনাইজেশন সরবরাহ করতে পারেন, তবে মূল বিষয়: এটি স্বয়ংক্রিয়ভাবে নিরাপদ নয়।
অ্যালিউরকোড

প্রকৃতপক্ষে, আমি বলছি, যতক্ষণ বৈশিষ্ট্য প্রশ্নে ফাংশনটির আচরণ পরিবর্তন করে না, এটি ভাল it's এর সাথে তুলনা করুন.__doc__
ডিমা তিস্নেক

এই পদ্ধতির অলঙ্কৃত ফাংশনটির সাথে আউটপুট বর্ণনা সংযুক্ত করার জন্যও ব্যবহার করা যেতে পারে, যা অজগর 2 এ অনুপস্থিত *
জুহ_

125

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

int fn(int i)
{
    static f = 1;
    f += i;
    return f;
}

আমি পাইথনে একইভাবে ফাংশনটি প্রয়োগ করতে পারি:

def fn(i):
    fn.f += i
    return fn.f
fn.f = 1

এটি স্পেকট্রামের "গালাগালি" শেষের দিকে অবশ্যই পড়ে যাবে।


2
মজাদার. পাইথনে স্ট্যাটিক ভেরিয়েবলগুলি প্রয়োগ করার অন্যান্য উপায় আছে কি?
এলি বেন্ডারস্কি

4
-1, এটি অজগর একটি জেনারেটর সঙ্গে প্রয়োগ করা হবে।

124
এই উত্তরটি হ্রাস করার পক্ষে এটি একটি দরিদ্র কারণ, যা সি এবং পাইথনের মধ্যে সাদৃশ্য প্রদর্শন করছে, এই নির্দিষ্ট ফাংশনটি লেখার সর্বোত্তম সম্ভাব্য উপায়ের পক্ষে নয়।
রবার্ট রসনি

3
@ রবার্টরোসনি তবে যদি জেনারেটরগুলি যদি উপায় হয় তবে এটি ফাংশনের বৈশিষ্ট্যগুলির একটি খারাপ ব্যবহার। যদি তাই হয়, তবে এটি আপত্তিজনক। যদিও
আপত্তিজনক পদক্ষেপগুলি উত্থাপন করা

1
অবশ্যই পিইপি 232 অনুসারে অপব্যবহারের মতো বলে মনে হচ্ছে, @ ইউজার140352, এবং হপের মন্তব্য এবং এই উত্তরটির উত্তর
হাবস

52

আপনি জাভাস্ক্রিপ্টের উপায়ে অবজেক্টগুলি করতে পারেন ... এতে কোনও লাভ হয় না তবে এটি কাজ করে;)

>>> def FakeObject():
...   def test():
...     print "foo"
...   FakeObject.test = test
...   return FakeObject
>>> x = FakeObject()
>>> x.test()
foo

36
+1 এই বৈশিষ্ট্যটির অপব্যবহারের একটি দুর্দান্ত উদাহরণ, যা প্রশ্ন জিজ্ঞাসা করা জিনিসগুলির মধ্যে একটি।
মাইকেল ডান

1
এটি মিপাডির উত্তর থেকে কীভাবে আলাদা? একই জিনিস বলে মনে হচ্ছে, কোনও int এর পরিবর্তে, বৈশিষ্ট্যটির মানটি একটি ফাংশন।
অ্যালিউরকোড

হয় def test()সত্যিই প্রয়োজনীয়?
কীর্তন প্রভাকরণ

15

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

def log(msg):
   log.logfile.write(msg)

এখন আমি logআমার মডিউল জুড়ে ব্যবহার করতে পারি এবং কেবল সেট করে আউটপুট পুনর্নির্দেশ করতে পারি log.logfile। এটি সম্পাদন করার জন্য প্রচুর এবং প্রচুর অন্যান্য উপায় রয়েছে তবে এটির হালকা ও ময়লা সহজ। এবং এটি প্রথমবারের মতো মজাদার গন্ধযুক্ত হওয়ার সময় আমি বিশ্বাস করে এসেছি যে এটি বৈশ্বিক logfileপরিবর্তনশীল হওয়ার চেয়ে গন্ধ পাচ্ছে।


7
গন্ধ আবার: যদিও এটি বিশ্বব্যাপী লগফায়াল থেকে মুক্তি পাবে না। এটি কেবলমাত্র অন্য এক বিশ্বব্যাপী লগ ফাংশনে এটিকে কাঠবিড়ালি করে দেয়।
অ্যালিওরকোড

2
@allyourcode: তবে একই মডিউলে বিভিন্ন ফাংশনের জন্য যদি আপনার একগুচ্ছ গ্লোবাল লগফাইলে থাকতে হয় তবে এটি নাম সংঘর্ষ এড়াতে সহায়তা করতে পারে।
ফায়ারগুরফিকু

11

ফাংশন বৈশিষ্ট্যগুলি হালকা ওজনের বন্ধগুলি লিখতে ব্যবহার করা যেতে পারে যা কোড এবং সম্পর্কিত ডেটা একসাথে लपेटায়:

#!/usr/bin/env python

SW_DELTA = 0
SW_MARK  = 1
SW_BASE  = 2

def stopwatch():
   import time

   def _sw( action = SW_DELTA ):

      if action == SW_DELTA:
         return time.time() - _sw._time

      elif action == SW_MARK:
         _sw._time = time.time()
         return _sw._time

      elif action == SW_BASE:
         return _sw._time

      else:
         raise NotImplementedError

   _sw._time = time.time() # time of creation

   return _sw

# test code
sw=stopwatch()
sw2=stopwatch()
import os
os.system("sleep 1")
print sw() # defaults to "SW_DELTA"
sw( SW_MARK )
os.system("sleep 2")
print sw()
print sw2()

1,00934004784

2,00644397736

3,01593494415


3
যখন ক্লাসগুলি সহজ হয় তখন কেন ফাংশনগুলিতে চাপ দিন? এবং আসুন ভুলে যাবেন না ক্লাসগুলি কোনও ফাংশন অনুকরণ করতে পারে।
Muhuk

1
এর time.sleep(1)চেয়েও ভালos.system('sleep 1')
বরিস গোরালিক

3
@bgbg সত্য, যদিও এই উদাহরণটি ঘুমের বিষয়ে নয়।
অ্যালিউরকোড

এটি অবশ্যই অপব্যবহার; এখানে ফাংশন ব্যবহার সম্পূর্ণ কৃতজ্ঞ। Muhuk ঠিক ঠিক: ক্লাস একটি ভাল সমাধান।
অ্যালিউরকোড

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

6

আমি সহজেই ফাংশন বৈশিষ্ট্যগুলি সেট করতে এই সহায়ক ডেকরেটারটি তৈরি করেছি:

def with_attrs(**func_attrs):
    """Set attributes in the decorated function, at definition time.
    Only accepts keyword arguments.
    E.g.:
        @with_attrs(counter=0, something='boing')
        def count_it():
            count_it.counter += 1
        print count_it.counter
        print count_it.something
        # Out:
        # >>> 0
        # >>> 'boing'
    """
    def attr_decorator(fn):
        @wraps(fn)
        def wrapper(*args, **kwargs):
            return fn(*args, **kwargs)

        for attr, value in func_attrs.iteritems():
            setattr(wrapper, attr, value)

        return wrapper

    return attr_decorator

ব্যবহারের ক্ষেত্রে হ'ল ফ্যাক্টরিগুলির একটি সংগ্রহ তৈরি করা এবং কোনও ফাংশন মেটা স্তরে তারা যে ডেটা তৈরি করতে পারে সেগুলি অনুসন্ধান করা।
উদাহরণস্বরূপ (খুব বোবা এক):

@with_attrs(datatype=list)
def factory1():
    return [1, 2, 3]

@with_attrs(datatype=SomeClass)
def factory2():
    return SomeClass()

factories = [factory1, factory2]

def create(datatype):
    for f in factories:
        if f.datatype == datatype:
            return f()
    return None

সাজসজ্জাকারী কীভাবে সাহায্য করে? factory1.datatype=listপুরানো শৈলীর সাজসজ্জার মতো ঠিক ঘোষণার নীচে ঠিক কেন সেট করা যায় না ?
Ceasar বাউটিস্তা

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

দ্রুত আপডেট: পাইথন 3 এর সাথে আপনার items()পরিবর্তে ব্যবহার করা দরকার iteritems()
স্কট মানে

4

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


আমি এই ধারনাটি পছন্দ করি! গণনা করা মানগুলি ক্যাশে করার জন্য আরও সাধারণ কৌশলটি হ'ল ডলারটিকে কোনও গুণকের সরবরাহকারীর ডিফল্ট মান হিসাবে ব্যবহার করা হয় যা কলার কখনই সরবরাহ করার উদ্দেশ্যে নয় - যেহেতু পাইথন মূল্যায়ন করে যে কেবলমাত্র ফাংশনটি সংজ্ঞায়িত করার সময় আপনি সেখানে তথ্য সংরক্ষণ করতে পারেন এবং এটি আটকে রাখতে পারেন কাছাকাছি. ফাংশন বৈশিষ্ট্যগুলি ব্যবহার করার সময় কম সুস্পষ্ট হতে পারে, এটি আমার কাছে উল্লেখযোগ্যভাবে কম হ্যাকি বোধ করে।
সোরেন বর্জনস্টাড

1

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


1
আমি সম্ভবত এটি বিভ্রান্তিকর সম্পর্কে আপনার মূল বক্তব্যের সাথে একমত, তবে পুনরায় ডকাস্ট্রিংস: হ্যাঁ, তবে ফাংশনগুলিতে কেন AD-HOC বৈশিষ্ট্য রয়েছে? ডাস্ট্রিংয়ের জন্য একটি নির্দিষ্ট বৈশিষ্ট্য থাকতে পারে fixed
অ্যালিউরকোড

@allyourcode ভাষায় নকশাকৃত নির্দিষ্ট অ্যাডহক কেসগুলির চেয়ে সাধারণ ক্ষেত্রে রাখা জিনিসগুলিকে সহজ করে তোলে এবং পাইথনের পুরানো সংস্করণগুলির সাথে সামঞ্জস্যতা বাড়ে। (উদাহরণস্বরূপ, ডক্টরিংগুলিকে সেট / পরিচালনা করে এমন কোডটি পাইথনের এমন একটি সংস্করণ নিয়ে কাজ করবে যা ডকাস্ট্রিংগুলি না করে, যতক্ষণ এটি বৈশিষ্ট্যটির অস্তিত্ব নেই এমন ক্ষেত্রে পরিচালনা করে))
সিজেএস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.