পাইথন __call__ বিশেষ পদ্ধতির ব্যবহারিক উদাহরণ


159

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

যদি কেউ আমাকে এই বিশেষ পদ্ধতির ব্যবহারিক ব্যবহার দেয় তবে আমি সত্যিই এটির প্রশংসা করব।



8
_ক্যাল_এর কার্যকারিতা ঠিক সি ++ তে () এর ওভারলোডেড অপারেটরের মতো । আপনি যদি ক্লাসের বাইরে কেবল একটি নতুন পদ্ধতি তৈরি করেন তবে আপনি কোনও শ্রেণীর অভ্যন্তরীণ ডেটা অ্যাক্সেস করতে পারবেন না।
অ্যান্ডি

2
এর সর্বাধিক সাধারণ ব্যবহার __call__প্লেইন ভিউতে লুকানো রয়েছে; : কিভাবে এটি আপনার একটি বর্গ instantiate এর x = Foo()সত্যিই x = type(Foo).__call__(Foo), যেখানে __call__এর ক্লাসের অধীনে একটি ক্লাস দ্বারা সংজ্ঞায়িত করা হয় Foo
চিপনার

উত্তর:


88

জ্যাঙ্গো ফর্ম মডিউল __call__ফর্ম বৈধতার জন্য একটি সামঞ্জস্যপূর্ণ এপিআই বাস্তবায়নের জন্য পদ্ধতিটি দুর্দান্তভাবে ব্যবহার করে । আপনি একটি ফাংশন হিসাবে জ্যাঙ্গোতে একটি ফর্মের জন্য আপনার নিজের বৈধকারক লিখতে পারেন।

def custom_validator(value):
    #your validation logic

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

class RegexValidator(object):
    def __call__(self, value):
        # validation logic

class URLValidator(RegexValidator):
    def __call__(self, value):
        super(URLValidator, self).__call__(value)
        #additional logic

class EmailValidator(RegexValidator):
    # some logic

এখন আপনার কাস্টম ফাংশন এবং অন্তর্নির্মিত ইমেলভালিডেটর উভয়কে একই সিনট্যাক্সের সাথে কল করা যেতে পারে।

for v in [custom_validator, EmailValidator()]:
    v(value) # <-----

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


5
সুতরাং যদি সঠিকভাবে ব্যবহৃত হয় তবে এটি কোডটিকে আরও পঠনযোগ্য করে তুলতে পারে। আমি ধরে নিয়েছি এটি যদি ভুল জায়গায় ব্যবহার করা হয় তবে এটি কোডটি খুব অপঠনযোগ্যও করে তুলবে।
mohi666

15
এটি কীভাবে এটি ব্যবহার করা যায় তার একটি উদাহরণ, তবে আমার মতে এটি ভাল নয়। এই ক্ষেত্রে কোনও কলযোগ্য উদাহরণ থাকার কোনও সুবিধা নেই। । লাডিয়েট () এর মতো একটি পদ্ধতির সাথে ইন্টারফেস / অ্যাবস্ট্রাক্ট ক্লাস রাখা ভাল; এটি একই জিনিসটি কেবল আরও স্পষ্ট। __Call__- এর আসল মান এমন কোনও স্থানে কল করতে পারে যেখানে প্রত্যাশিত প্রত্যাশা থাকে use উদাহরণস্বরূপ, সজ্জকার তৈরি করার সময় আমি প্রায়শই __call__ ব্যবহার করি।
ড্যানিয়েল

120

এই উদাহরণটি মেমোয়েজেশন ব্যবহার করে , মূলত একটি সারণীতে মান সংরক্ষণ করে (এই ক্ষেত্রে অভিধান) যাতে আপনি এগুলি পুনরায় গণনার পরিবর্তে পরে এগুলি সন্ধান করতে পারেন।

এখানে আমরা স্ট্যাটিক ভেরিয়েবল (পাইথনের ক্ষেত্রে যেমনটি সম্ভব নয়) যুক্ত ফ্যাক্টরিয়াল ফাংশনের পরিবর্তে __call__ফ্যাক্টরিয়ালগুলি ( কলযোগ্য বস্তুর মাধ্যমে ) গণনা করার জন্য একটি পদ্ধতি সহ একটি সাধারণ ক্লাস ব্যবহার করি ।

class Factorial:
    def __init__(self):
        self.cache = {}
    def __call__(self, n):
        if n not in self.cache:
            if n == 0:
                self.cache[n] = 1
            else:
                self.cache[n] = n * self.__call__(n-1)
        return self.cache[n]

fact = Factorial()

এখন আপনার কাছে অন্য একটি factফাংশনের মতো একটি অবজেক্ট রয়েছে যা কলযোগ্য। উদাহরণ স্বরূপ

for i in xrange(10):                                                             
    print("{}! = {}".format(i, fact(i)))

# output
0! = 1
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
6! = 720
7! = 5040
8! = 40320
9! = 362880

এবং এটি রাষ্ট্রীয়ও বটে।


2
আমি বরং এমন একটি factবস্তু চাই যা সূচকযোগ্য কারণ আপনার __call__ফাংশনটি মূলত একটি সূচক index এছাড়াও ডিকের পরিবর্তে একটি তালিকা ব্যবহার করা হবে তবে এটি কেবল আমার।
ক্রিস লুটজ

4
@ ডেলানান - প্রায় কোনও কিছু বিভিন্ন স্বতন্ত্র উপায়ে করা যেতে পারে। যার বেশি পাঠযোগ্য তা পাঠকের উপর নির্ভর করে।
ক্রিস লুৎজ

1
@ ক্রিস লুটজ: আপনি এই ধরণের পরিবর্তন বিবেচনা করতে মুক্ত। সাধারণভাবে স্মৃতিচারণের জন্য , একটি অভিধান ভালভাবে কাজ করে কারণ আপনি যে জিনিসগুলিতে আপনার তালিকা পূরণ করবেন সেটির গ্যারান্টি দিতে পারবেন না। এই ক্ষেত্রে, একটি তালিকা কাজ করতে পারে তবে এটি কোনও দ্রুত বা সহজ হতে পারে না।
এস.লট

8
@ ডেলানান: এটি সবচেয়ে কম হওয়ার উদ্দেশ্যে নয়। কোড গল্ফে কেউ জিতেনি। এটি দেখানোর উদ্দেশ্যে __call__, সহজ হতে এবং আরও কিছু না।
এস.লট

3
কিন্তু যখন এটি প্রদর্শিত উদাহরণস্বরূপ কৌশলগুলি কাজগুলির জন্য আদর্শ না হয়, তাই না? (এবং আমি "এর হ্যাকের জন্য লাইনগুলি সংরক্ষণ করি" - শর্ট সম্পর্কে ছিলাম না, আমি "এটিকে একইভাবে পরিষ্কার পদ্ধতিতে লিখি এবং কিছু বয়লারপ্লেট কোড সংরক্ষণ করি" - শর্ট সম্পর্কে আশ্বাস দিয়েছিলাম যে আমি নই এই পাগলদের মধ্যে একটির দ্বারা সংক্ষিপ্ততম কোডটি লেখার চেষ্টা করা হচ্ছে, আমি কেবল বয়লারপ্লেট কোডটি এড়াতে চাই যা পাঠকের জন্য কিছুই যোগ করে না))

40

আমি এটি দরকারী বলে মনে করি কারণ এটি আমাকে এমন APIs তৈরি করতে দেয় যা ব্যবহার করা সহজ (আপনার কাছে কিছু কলযোগ্য বস্তু রয়েছে যার জন্য কিছু নির্দিষ্ট যুক্তি প্রয়োজন), এবং প্রয়োগ করা সহজ কারণ আপনি অবজেক্ট ওরিয়েন্টেড অনুশীলনগুলি ব্যবহার করতে পারেন।

নিম্নলিখিতটি আমি গতকাল লিখেছি এমন কোড যা hashlib.fooপদ্ধতিগুলির একটি সংস্করণ তৈরি করে যা স্ট্রিংয়ের পরিবর্তে সম্পূর্ণ ফাইল হ্যাশ করে:

# filehash.py
import hashlib


class Hasher(object):
    """
    A wrapper around the hashlib hash algorithms that allows an entire file to
    be hashed in a chunked manner.
    """
    def __init__(self, algorithm):
        self.algorithm = algorithm

    def __call__(self, file):
        hash = self.algorithm()
        with open(file, 'rb') as f:
            for chunk in iter(lambda: f.read(4096), ''):
                hash.update(chunk)
        return hash.hexdigest()


md5    = Hasher(hashlib.md5)
sha1   = Hasher(hashlib.sha1)
sha224 = Hasher(hashlib.sha224)
sha256 = Hasher(hashlib.sha256)
sha384 = Hasher(hashlib.sha384)
sha512 = Hasher(hashlib.sha512)

এই প্রয়োগটি আমাকে ফাংশনগুলির সাথে একই ধরণের ফাংশনগুলি ব্যবহার করতে দেয় hashlib.foo:

from filehash import sha1
print sha1('somefile.txt')

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


7
আবার ক্লোজারগুলি এই উদাহরণটিকে নষ্ট করে। পেস্টবিন.com/961vU0ay 80% লাইন এবং ঠিক যেমনটি পরিষ্কার।

8
আমি নিশ্চিত নই যে এটি সর্বদা কারও কাছে ঠিক যেমন পরিষ্কার হবে (যেমন সম্ভবত এমন কেউ যিনি কেবল জাভা ব্যবহার করেছেন)। নেস্টেড ফাংশন এবং ভেরিয়েবল লুক / স্কোপ বিভ্রান্তিকর হতে পারে। আমি মনে করি আমার __call__বক্তব্যটি আপনাকে এমন একটি সরঞ্জাম দেয় যা আপনাকে সমস্যার সমাধানের জন্য ওও কৌশলগুলি ব্যবহার করতে দেয়।
bradley.ayers

4
আমি মনে করি যে উভয়ই সমতুল্য কার্যকারিতা সরবরাহ করলে কেন "ওভার এক্স এক্স ব্যবহার করবেন" প্রশ্নটি অত্যন্ত সাবজেক্টিভ। কিছু লোকের জন্য ওও পদ্ধতির বোঝা সহজ, অন্যদের কাছে ক্লোজার অ্যাপ্রোচ। একে অপরের উপর ব্যবহার করার জন্য কোন বাধ্যতামূলক যুক্তি নেই, যদি না আপনার যদি এমন পরিস্থিতি তৈরি হয় যেখানে আপনাকে ব্যবহার করতে হয়েছিলisinstance বা অনুরূপ কিছু ছিল
bradley.ayers 21

2
@ ডেলানান আপনার বন্ধের উদাহরণ কোডের কম লাইন, তবে এটি ঠিক যেমন স্পষ্ট তর্ক করা আরও কঠিন to
ডেনিস

8
আপনি __call__যখন মাল্টিপ্রসেসিং মডিউলটি ব্যবহার করছেন তখন প্রক্রিয়াগুলির মধ্যে তথ্য পাস করার জন্য পিকিং ব্যবহার করে, বন্ধ করার পরিবর্তে আপনি কোথায় কোনও পদ্ধতি ব্যবহার করবেন তার একটি উদাহরণ । আপনি একটি ক্লোজিংকে আচার করতে পারবেন না, তবে আপনি কোনও ক্লাসের উদাহরণটি আচার করতে পারেন।
জন পিটার থম্পসন গার্সিস

21

__call__পাইথনে ডেকরেটার ক্লাস প্রয়োগ করতেও ব্যবহৃত হয়। সেক্ষেত্রে ডেকোরেটার সহ পদ্ধতিটি ডাকা হলে শ্রেণীর উদাহরণ বলা হয়।

class EnterExitParam(object):

    def __init__(self, p1):
        self.p1 = p1

    def __call__(self, f):
        def new_f():
            print("Entering", f.__name__)
            print("p1=", self.p1)
            f()
            print("Leaving", f.__name__)
        return new_f


@EnterExitParam("foo bar")
def hello():
    print("Hello")


if __name__ == "__main__":
    hello()

9

হ্যাঁ, আপনি যখন জানেন যে আপনি অবজেক্টগুলির সাথে লেনদেন করছেন, তখন একটি সুস্পষ্ট পদ্ধতি কল ব্যবহার করা পুরোপুরি সম্ভব (এবং বেশিরভাগ ক্ষেত্রেই পরামর্শ দেওয়া যায়)। যাইহোক, কখনও কখনও আপনি কোডটি মোকাবেলা করেন যা কলযোগ্য বস্তুগুলি প্রত্যাশা করে - সাধারণত ফাংশনগুলি, তবে __call__আপনাকে ধন্যবাদ আরও জটিল জটিল অবজেক্ট তৈরি করতে পারে, উদাহরণস্বরূপ ডেটা এবং পুনরাবৃত্ত কাজগুলি অর্পণ করার আরও বেশি পদ্ধতি ইত্যাদি যা এখনও কলযোগ্য।

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

class Worker(object):
    def __init__(self, *args, **kwargs):
        self.queue = queue.Queue()
        self.args = args
        self.kwargs = kwargs

    def add_task(self, task):
        self.queue.put(task)

    def __call__(self):
        while True:
            next_action = self.queue.get()
            success = next_action(*self.args, **self.kwargs)
            if not success:
               self.add_task(next_action)

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


3
এখানে "হাঁসের টাইপিং" ( en.wikedia.org/wiki/Duck_typing#In_Python ) বাক্যাংশটি ব্যবহার করা সম্ভবত কার্যকর - আপনি আরও জটিল শ্রেণীর অবজেক্টটি এভাবে ব্যবহার করে কোনও ফাংশন নকল করতে পারেন ।
অ্যান্ড্রু জাফি

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

5

ক্লাস-ভিত্তিক সজ্জাবিদ __call__মোড়ানো ফাংশনটি উল্লেখ করতে ব্যবহার করেন। উদাহরণ:

class Deco(object):
    def __init__(self,f):
        self.f = f
    def __call__(self, *args, **kwargs):
        print args
        print kwargs
        self.f(*args, **kwargs)

আর্টিমা ডটকম এ এখানে বিভিন্ন বিকল্পের একটি ভাল বর্ণনা রয়েছে


যদিও আমি ক্লাসের সজ্জাগুলি খুব কমই দেখি, কারণ তাদের পদ্ধতিগুলির সাথে কাজ করার জন্য কিছু অবিশ্বাস্য বয়লারপ্লিট কোড প্রয়োজন।

4

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


4

আমি সবেমাত্র __call__()কনসার্টে ব্যবহারের ক্ষেত্রে হোঁচট খেয়েছি__getattr__() যার সাথে আমার মনে হয় সুন্দর is এটি আপনাকে কোনও জিনিসের ভিতরে একটি JSON / HTTP / (তবে_সরিয়ালাইজড) API এর একাধিক স্তর আড়াল করতে দেয়।

__getattr__()অংশ iteratively এই একই ক্লাসের একটি পরিবর্তিত উদাহরণস্বরূপ ফিরে, একটি সময়ে আরও একটি বৈশিষ্ট্য পূরণ যত্ন নেয়। তারপরে, সমস্ত তথ্য নিঃশেষ হয়ে যাওয়ার পরে, __call__()আপনি যে কোনও যুক্তি দিয়ে গেছেন তা গ্রহণ করে।

এই মডেলটি ব্যবহার করে, আপনি উদাহরণস্বরূপ কল করতে পারেন api.v2.volumes.ssd.update(size=20), যা একটি পুট অনুরোধে শেষ হয় https://some.tld/api/v2/volumes/ssd/update

নির্দিষ্ট কোডটি ওপেনস্ট্যাকের একটি নির্দিষ্ট ভলিউম ব্যাকএন্ডের জন্য একটি ব্লক স্টোরেজ ড্রাইভার, আপনি এটি এখানে দেখতে পারেন: https://github.com/openstack/cinder/blob/master/cinder/volume/drivers/nexenta/jsonrpc.py

সম্পাদনা: মাস্টার রিভিশন থেকে নির্দেশিত লিঙ্কটি আপডেট হয়েছে Updated


ওটা সুন্দর. আমি একবার অ্যাট্রিবিউট অ্যাক্সেস ব্যবহার করে একটি স্বেচ্ছাসেবী এক্সএমএল গাছকে অনুসরণ করার জন্য একই প্রক্রিয়াটি ব্যবহার করেছি।
পেট্রি

1

একটি নির্দিষ্ট করুন __metaclass__এবং __call__পদ্ধতিটিকে ওভাররাইড করুন এবং নির্দিষ্ট মেটা ক্লাসগুলির __new__পদ্ধতিটি ক্লাসের একটি উদাহরণ ফিরিয়ে আনুন, ভায়োলা পদ্ধতিগুলির সাথে আপনার "ফাংশন" রয়েছে।


1

__call__স্ট্যাটিক পদ্ধতি হিসাবে আমরা অন্যান্য শ্রেণির পদ্ধতি ব্যবহার করার জন্য পদ্ধতিটি ব্যবহার করতে পারি ।

    class _Callable:
        def __init__(self, anycallable):
            self.__call__ = anycallable

    class Model:

        def get_instance(conn, table_name):

            """ do something"""

        get_instance = _Callable(get_instance)

    provs_fac = Model.get_instance(connection, "users")             

0

একটি সাধারণ উদাহরণ হ'ল __call__ইন functools.partial, এখানে একটি সরলীকৃত সংস্করণ (পাইথন> = 3.5 সহ):

class partial:
    """New function with partial application of the given arguments and keywords."""

    def __new__(cls, func, *args, **kwargs):
        if not callable(func):
            raise TypeError("the first argument must be callable")
        self = super().__new__(cls)

        self.func = func
        self.args = args
        self.kwargs = kwargs
        return self

    def __call__(self, *args, **kwargs):
        return self.func(*self.args, *args, **self.kwargs, **kwargs)

ব্যবহার:

def add(x, y):
    return x + y

inc = partial(add, y=1)
print(inc(41))  # 42

0

ফাংশন কল অপারেটর।

class Foo:
    def __call__(self, a, b, c):
        # do something

x = Foo()
x(1, 2, 3)

__Call__ পদ্ধতি পুনরায় সংজ্ঞায়িত / পুনরায় আরম্ভ করতে একই বস্তুর ব্যবহার করা যাবে। এটি কোনও শ্রেণীর উদাহরণস্বরূপ / অবজেক্টগুলিকে অবজেক্টগুলিতে যুক্তি দিয়ে ফাংশন হিসাবে ব্যবহার করতে সহায়তা করে facil


এটি কখন কার্যকর হবে? ফু (1, 2, 3) আরও পরিষ্কার মনে হয়।
ইয়ারোস্লাভ নিকিতেনকো

0

আমি একটি ভাল জায়গা callable বস্তু ব্যবহার করতে খুঁজতে ঐ যে সংজ্ঞায়িত __call__()যখন পাইথন মধ্যে কার্যকরী প্রোগ্রামিং ক্ষমতা ব্যবহার করে, যেমন হয় map(), filter(), reduce()

প্লেন ফাংশন বা ল্যাম্বডা ফাংশনের উপরে কলযোগ্য বস্তুটি ব্যবহার করার সর্বোত্তম সময়টি হ'ল লজিকটি জটিল এবং কিছু স্থিতি বজায় রাখার প্রয়োজন হয় বা অন্য তথ্য ব্যবহার করে যা __call__()ফাংশনে পাস হয়নি ।

এখানে কিছু কোড রয়েছে যা কলযোগ্য বস্তু ব্যবহার করে এবং তাদের ফাইল নাম এক্সটেনশনের উপর ভিত্তি করে ফাইলের নাম ফিল্টার করে filter()

Callable:

import os

class FileAcceptor(object):
    def __init__(self, accepted_extensions):
        self.accepted_extensions = accepted_extensions

    def __call__(self, filename):
        base, ext = os.path.splitext(filename)
        return ext in self.accepted_extensions

class ImageFileAcceptor(FileAcceptor):
    def __init__(self):
        image_extensions = ('.jpg', '.jpeg', '.gif', '.bmp')
        super(ImageFileAcceptor, self).__init__(image_extensions)

ব্যবহার:

filenames = [
    'me.jpg',
    'me.txt',
    'friend1.jpg',
    'friend2.bmp',
    'you.jpeg',
    'you.xml']

acceptor = ImageFileAcceptor()
image_filenames = filter(acceptor, filenames)
print image_filenames

আউটপুট:

['me.jpg', 'friend1.jpg', 'friend2.bmp', 'you.jpeg']

0

এটি অনেক দেরি হয়ে গেছে তবে আমি একটি উদাহরণ দিচ্ছি। আপনার একটি Vectorক্লাস এবং ক্লাস আছে তা কল্পনা করুন Point। উভয়ই x, yঅবস্থানগত আর্গুমেন্ট হিসাবে গ্রহণ করে । আসুন কল্পনা করুন যে আপনি কোনও ফাংশন তৈরি করতে চান যা ভেক্টরটিতে রাখার জন্য পয়েন্টটি প্রেরণ করে।

4 সমাধান

  • put_point_on_vec(point, vec)

  • এটি ভেক্টর শ্রেণিতে একটি পদ্ধতি করুন। যেমন my_vec.put_point(point)

  • এটি Pointক্লাসে একটি পদ্ধতি করুন ।my_point.put_on_vec(vec)
  • Vectorপ্রয়োগগুলি __call__, যাতে আপনি এটি পছন্দ করতে পারেনmy_vec_instance(point)

এটি আসলে এমন কয়েকটি উদাহরণের অংশ যা আমি গাঠিত পদ্ধতিগুলির জন্য ব্যাখ্যা করার জন্য গাইডের জন্য কাজ করছি যা আমি শিগগিরই বা মুক্তি পাব onna

আমি পয়েন্টটি নিজেই সরানোর যুক্তিটি ছেড়ে দিয়েছি কারণ এই প্রশ্নটি এটাই নয়

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