অজগর অভিধানের ভিতরে একটি ফাংশন কেন সঞ্চয় করবেন?


68

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


কৌশলটি হল যখন আপনি একটি অজগর অভিধান এবং একটি ফাংশন যা আপনি এটি ব্যবহার করতে চান। আপনি ডিকের মধ্যে একটি অতিরিক্ত উপাদান .োকান, যার মান ফাংশনের নাম of আপনি যখন ফাংশনটি কল করতে প্রস্তুত হন তখন ডিক উপাদানটি উল্লেখ করে কলটি পরোক্ষভাবে জারি করেন , নামটি দিয়ে ফাংশনটি নয়।

পাইথন দ্য হার্ড ওয়ে, ২ য় এড থেকে আমি যে উদাহরণটি নিয়ে কাজ করছি is (আপনি উডেমি ডটকমের মাধ্যমে সাইন আপ করার সময় এটি উপলব্ধ সংস্করণ ; দুর্ভাগ্যক্রমে লাইভ ফ্রি এইচটিএমএল সংস্করণটি বর্তমানে এড 3, এবং এই উদাহরণটি আর অন্তর্ভুক্ত করে না)।

প্যারাফ্রেজ করতে:

# make a dictionary of US states and major cities
cities = {'San Diego':'CA', 'New York':'NY', 'Detroit':'MI'}

# define a function to use on such a dictionary
def find_city (map, city):
    # does something, returns some value
    if city in map:
        return map[city]
    else:
        return "Not found"

# then add a final dict element that refers to the function
cities['_found'] = find_city

তারপরে নিম্নলিখিত অভিব্যক্তিগুলি সমতুল্য। আপনি সরাসরি ফাংশনটি কল করতে পারেন বা ডিক উপাদানটির উল্লেখ করে যার মূল্যটি ফাংশন।

>>> find_city (cities, 'New York')
NY

>>> cities['_found'](cities, 'New York')
NY

এটির ভাষা বৈশিষ্ট্য কোনটি ব্যাখ্যা করতে পারে এবং এটি "বাস্তব" প্রোগ্রামিংয়ে কোথায় আসে? এই খেলনা অনুশীলনটি আমাকে সিনট্যাক্স শেখানোর জন্য যথেষ্ট ছিল, তবে আমাকে সেখানে পুরোপুরি নেয়নি।


13
কেন এই পোস্টটি অফ-টপিক হবে? এটি একটি দুর্দান্ত অ্যালগরিদম এবং ডেটা স্ট্রাকচার ধারণার প্রশ্ন!
মার্টিজন পিটারস

আমি অন্যান্য ভাষায় এর মতো কিছু জিনিস দেখেছি (এবং করেছি)। আপনি এটিকে স্যুইচ স্টেটমেন্ট হিসাবে বাছাই করতে পারেন, তবে ও (1) দেখার সময় সহ একটি প্যাসেবল অবজেক্টে ভালভাবে গুটিয়ে রাখতে পারেন।
কেচালোক্স

1
আমার একটা কুঁড়েঘর ছিল তার নিজস্ব ডিকের ভিতরে ফাংশনটি অন্তর্ভুক্ত করার বিষয়ে কিছু গুরুত্বপূর্ণ & স্ব-রেফারেন্সিয়াল ছিল ... দেখুন @ ডায়েটবুদ্ধের উত্তর ... তবে সম্ভবত না?
mdeutschmtl

উত্তর:


83

ডিক ব্যবহার করে আসুন আপনি কলটি কলটিতে কীটি অনুবাদ করতে পারেন। আপনার উদাহরণ হিসাবে, কীটি হার্ডকোড করার দরকার নেই।

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

def do_ping(self, arg):
    return 'Pong, {0}!'.format(arg)

def do_ls(self, arg):
    return '\n'.join(os.listdir(arg))

dispatch = {
    'ping': do_ping,
    'ls': do_ls,
}

def process_network_command(command, arg):
    send(dispatch[command](arg))

নোট করুন যে আমরা এখন যে ফাংশনটি কল করি তা পুরোপুরি নির্ভর করে যে মানটি কী command। চাবিটিও মেলতে হবে না; এমনকি এটি স্ট্রিংও হতে পারে না, আপনি কী হিসাবে ব্যবহার করা যেতে পারে এমন কোনও কিছু ব্যবহার করতে পারেন এবং আপনার নির্দিষ্ট অ্যাপ্লিকেশনটির সাথে খাপ খায়।

প্রেরণ পদ্ধতিটি অন্যান্য কৌশলগুলির চেয়ে নিরাপদ eval(), যেমন এটি পূর্বে আপনি যে সংজ্ঞা দিয়েছিলেন তাতে অনুমতিযোগ্য আদেশগুলি সীমাবদ্ধ করে। ls)"; DROP TABLE Students; --উদাহরণস্বরূপ কোনও আক্রমণকারী কোনও প্রেরণ টেবিলের অতীতে কোনও ইনজেকশন ছিনিয়ে নিতে যাবেন না ।


5
@ মার্টজিন - এটিকে কী 'কমান্ড প্যাটার্ন' এর বাস্তবায়ন বলা যায় না? ওপিও যে ধারণাটি ধরার চেষ্টা করছে তা দেখে মনে হচ্ছে?
পিএইচডি

3
@ পিএইচডি: হ্যাঁ, আমি যে উদাহরণটি তৈরি করেছি তা হ'ল কমান্ড প্যাটার্ন বাস্তবায়ন; dictডেস্প্যাচার হিসাবে কাজ (কমান্ড ম্যানেজার, invoker, ইত্যাদি)।
মার্টিজন পিটারস

@ মার্তিজন, দুর্দান্ত শীর্ষ স্তরের ব্যাখ্যা thanks আমি মনে করি আমি "প্রেরণ" ধারণাটি পেয়েছি।
mdeutschmtl

28

@ মার্তিজন পিটারগুলি কৌশলটি ব্যাখ্যা করার জন্য একটি ভাল কাজ করেছেন, তবে আমি আপনার প্রশ্ন থেকে কিছু স্পষ্ট করতে চাই।

গুরুত্বপূর্ণ বিষয়টি হ'ল আপনি অভিধানে "ফাংশনটির নাম" সংরক্ষণ করছেন না । আপনি নিজেই ফাংশনটির একটি রেফারেন্স সঞ্চয় করছেন। আপনি এটি ফাংশনটিতে একটি ব্যবহার করে দেখতে পারেন print

>>> def f():
...   print 1
... 
>>> print f
<function f at 0xb721c1b4>

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

>>> a = f
>>> a
<function f at 0xb721c3ac>
>>> a()
1

একইভাবে, আপনি একটি আর্গুমেন্ট হিসাবে একটি ফাংশন পাস করতে পারেন।

>>> def c(func):
...   func()
... 
>>> c(f)
1

5
প্রথম শ্রেণির ফাংশন উল্লেখ করা অবশ্যই অবশ্যই সহায়তা করবে :-)
ফ্লোরিয়ান মার্জাইন

7

দ্রষ্টব্য যে পাইথন ক্লাসটি আসলে অভিধানের জন্য কেবল একটি সিনট্যাক্স চিনি। যখন তুমি কর:

class Foo(object):
    def find_city(self, city):
        ...

আপনি কল যখন

f = Foo()
f.find_city('bar')

সত্যিই ঠিক যেমন:

getattr(f, 'find_city')('bar')

নাম সমাধানের পরে যা ঠিক তেমন:

f.__class__.__dict__['find_city'](f, 'bar')

একটি দরকারী কৌশল হ'ল কলব্যাকগুলিতে ব্যবহারকারীদের ইনপুট ম্যাপিং। উদাহরণ স্বরূপ:

def cb1(...): 
    ...
funcs = {
    'cb1': cb1,
    ...
}
while True:
    input = raw_input()
    funcs[input]()

এটি বিকল্পভাবে ক্লাসে লেখা যেতে পারে:

class Funcs(object):
    def cb1(self, a): 
        ...
funcs = Funcs()
while True:
    input = raw_input()
    getattr(funcs, input)()

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


আমি মনে করি এই আদান-প্রদানের বিষয়টিই আমাকে "পাইথোনিক" ভাবতে বাধ্য করেছে, আপনি সত্য যে পৃষ্ঠের উপরে যা দেখেন তা কেবল আরও গভীর কিছু উপস্থাপনের একটি প্রচলিত উপায়। পাইথন অনুশীলনগুলি (এবং পাইথন প্রোগ্রামাররা?) যদিও ভাষা বৈশিষ্ট্যগুলি সম্পর্কে এইরকম ভয়ঙ্কর কিছু বলে মনে হচ্ছে তবে তা অজগরটির পক্ষে বিশেষ নয়।
mdeutschmtl

আরেকটি চিন্তা, দু'টো পদ যেমন একে অপরের সাথে সংলগ্ন, ডিক রেফারেন্স এবং যুক্তি তালিকার মতো দেখতে কেমন লাগে তা মূল্যায়ন করতে ইচ্ছুকভাবে অজগরকে নির্দিষ্ট করার মতো কিছু আছে কি? অন্যান্য ভাষাগুলি কি এটিকে অনুমতি দেয়? এটা তোলে থেকে বীজগণিত লিপ প্রোগ্রামিং সমতুল্য সাজান 5 * xকরার 5x(সাধারণ উপমা ক্ষমা)।
mdeutschmtl

@ এমডিটস্মিটল: পাইথনের কাছে এটি সত্যই অনন্য নয়, যদিও যে ভাষাগুলিতে প্রথম শ্রেণির ফাংশন বা ফাংশন অবজেক্টের অভাব রয়েছে তার কোনও ক্ষেত্রেই এমন পরিস্থিতি নাও থাকতে পারে যেখানে ফাংশন কলের পরে তত্ক্ষণাত কোনও অভিধান অ্যাক্সেস সম্ভব হতে পারে possible
মিথ্যা রায়ান

2
@mdeutschmtl "এই সত্য যে আপনি পৃষ্ঠের উপরে যা দেখছেন তা হ'ল আরও গভীর কিছু উপস্থাপনের একটি প্রচলিত উপায়" " - যাকে সিনট্যাকটিক চিনি বলা হয় এবং এটি পুরো জায়গাতেই বিদ্যমান
ইজকাটা

6

আমার মনে এমন দুটি কৌশল রয়েছে যেগুলি আপনি উল্লেখ করছেন, যার মধ্যে কোনটি পাইথোনিক নয় যে এগুলি এক ভাষার চেয়ে বেশি বিস্তৃত।

1. তথ্য গোপন / এনক্যাপসুলেশন এবং সংহতি করার কৌশল (তারা সাধারণত হাতের মুঠোয় যায় তাই আমি এগুলিকে একসাথে নিচ্ছি)।

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

টেবিল প্রেরণ

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

Tradeoffs

একটি বিষয় লক্ষণীয় হ'ল কীগুলি আপনার পরিচিত নেমস্পেসের সাথে ভাল করে কাজ করবে। তবে, আপনি কী এবং অজানা নামের জায়গার সাথে ডেটা এবং ফাংশনগুলির মধ্যে সংঘর্ষের ঝুঁকিটি চালান।


এনক্যাপসুলেশন কারণ ডিক (আয়নারি) এ সঞ্চিত ডেটা এবং ফাংশন সম্পর্কিত, এবং এইভাবে সংহতি রয়েছে। ডেটা এবং ফাংশন দুটি খুব আলাদা ডোমেন থেকে, তাই প্রথম নজরে উদাহরণটি মনে হয় বন্যভাবে পৃথক পৃথক সত্ত্বাকে একসাথে লম্পিং করছে।
চককট্রিল

0

আমি এই সমাধানটি পোস্ট করি যা আমার মনে হয় যে বেশ জেনেরিক এবং এটি কার্যকর হতে পারে কারণ এটি সাধারণ ক্ষেত্রে নির্দিষ্ট ক্ষেত্রে খাপ খাইয়ে নেওয়া সহজ এবং সহজ রাখে:

def p(what):
    print 'playing', cmpsr

def l(what):
    print 'listening', cmpsr

actions = {'Play' : p, 'Listen' : l}

act = 'Listen'
cmpsr = 'Vivaldi'

actions[act].__call__(cmpsr)

যে কোনও উপাদান একটি ফাংশন অবজেক্ট এবং __call__অন্তর্নির্মিত পদ্ধতিটি ব্যবহার করতে পারে এমন একটি তালিকাও সংজ্ঞায়িত করতে পারে । অনুপ্রেরণা এবং সহযোগিতার জন্য ক্রেডিট।

"দুর্দান্ত শিল্পী হলেন সরলকরণকারী ", হেনরি ফ্রেডেরিক অ্যামিল

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