পাইথনে রেফারেন্স দিয়ে পূর্ণসংখ্যা পাস করা


97

পাইথনে রেফারেন্স দিয়ে আমি কীভাবে একটি পূর্ণসংখ্যা পাস করতে পারি?

আমি একটি ভেরিয়েবলের মানটি সংশোধন করতে চাই যা আমি ফাংশনটিতে যাচ্ছি। আমি পড়েছি পাইথনের প্রতিটি জিনিসই মূল্য দিয়ে যায় তবে একটি সহজ কৌশল থাকতে হবে। উদাহরণস্বরূপ, জাভা তোমাদের রেফারেন্স ধরনের পাস পারে Integer, Longইত্যাদি

  1. আমি কীভাবে কোনও রেফারেন্স দিয়ে কোনও ক্রিয়াকলাপটি পাস করতে পারি?
  2. সেরা অনুশীলনগুলি কী কী?

কোনও অজ্ঞাত শ্রেণিতে আপনার ints জড়ানোর জন্য যদি সামান্য সংশ্লেষিত উপায় (যা পরিবর্তনযোগ্য) যা 'রেফারেন্স'-এর মতো আচরণ করবে: স্ট্যাকওভারফ্লো.com/ a/ 1123054 / 409638 অর্থাত্ রেফ = টাইপ (' ', ()) , {'n': 1})
রবার্ট

উত্তর:


107

পাইথনে এটি তেমন কাজ করে না। পাইথন বস্তুর রেফারেন্স পাস করে। আপনার ক্রিয়াকলাপের ভিতরে আপনার একটি অবজেক্ট রয়েছে - আপনি সেই বস্তুকে (যদি সম্ভব হয়) রূপান্তর করতে পারেন। যাইহোক, পূর্ণসংখ্যা অপরিবর্তনীয় । একটি কর্মক্ষেত্র হ'ল একটি পাত্রে পূর্ণসংখ্যা পাস করা যা পরিবর্তিত হতে পারে:

def change(x):
    x[0] = 3

x = [1]
change(x)
print x

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

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

সাধারণত কর্মক্ষেত্রটি হ'ল আপনি যে জিনিসটি চান তা কেবল ফিরিয়ে দেওয়া :

def multiply_by_2(x):
    return 2*x

x = 1
x = multiply_by_2(x)

* উপরের প্রথম উদাহরণের ক্ষেত্রে, 3আসলে পাস হয়ে যায় x.__setitem__


11
"পাইথন বস্তু পাস করে।" পাইথন রেফারেন্সগুলি (বস্তুর দিকে নির্দেশক) পাস করে।
ব্যবহারকারী 102008

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

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

4
আমরা পরিভাষা নিয়ে বিভ্রান্ত হচ্ছি তা অবাক হওয়ার কিছু নেই। এখানে আমরা এটি কল-বাই-অবজেক্ট হিসাবে বর্ণনা করেছি এবং এখানে এটি পাস-বাই-মান হিসাবে বর্ণনা করা হয়েছে । অন্য কোথাও এটিকে "পাস-বাই-রেফারেন্স" বলা হয় যার অর্থ আসলে কী বোঝায় তার উপর ... মূলত, সমস্যাটি হল যে সম্প্রদায়টি কী বলা যায় তা বুঝতে পারে নি
মিলিলেসন

4
পাইথন রেফারেন্সগুলি জাভা রেফারেন্সগুলির মতো ঠিক একই। এবং জাভা রেফারেন্সগুলি বস্তুর প্রতি জেএলএস পয়েন্টার অনুসারে। এবং মূলত জাভা / পাইথন রেফারেন্স এবং সি ++ পয়েন্টারগুলির মধ্যে শব্দার্থবিজ্ঞানের বস্তুগুলিতে একটি সম্পূর্ণ দ্বিধা রয়েছে এবং অন্য কোনও কিছুই এই শব্দার্থবিজ্ঞানের বর্ণনা দেয় না। "সেগুলি ডিপ্রিফারেন্স করতে হবে না" আচ্ছা, .অপারেটর কেবল বাম দিকটি অবলম্বন করে। অপারেটরগুলি বিভিন্ন ভাষায় আলাদা হতে পারে।
ব্যবহারকারী 102008

31

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

এখানে একটি সাধারণ উদাহরণ:

def RectToPolar(x, y):
    r = (x ** 2 + y ** 2) ** 0.5
    theta = math.atan2(y, x)
    return r, theta # return 2 things at once

r, theta = RectToPolar(3, 4) # assign 2 things at once

9

সরাসরি কোনও মান পাস করা নয়, তবে এটি ব্যবহার করে যেমন এটি পাস হয়ে গেছে।

x = 7
def my_method():
    nonlocal x
    x += 1
my_method()
print(x) # 8

গুহাত:

  • nonlocal পাইথন 3 এ চালু হয়েছিল
  • যদি এনকোলেসিংয়ের সুযোগটি বিশ্বব্যাপী হয় তবে globalপরিবর্তে ব্যবহার করুন nonlocal

7

সত্যই, সর্বোত্তম অনুশীলন হ'ল পিছনে পদক্ষেপ নেওয়া এবং জিজ্ঞাসা করা আপনার সত্যিই এটি করা দরকার কিনা। আপনি কেন এমন ভেরিয়েবলের মানটি সংশোধন করতে চান যা আপনি ফাংশনে প্রবেশ করছেন?

আপনার যদি দ্রুত হ্যাক করার প্রয়োজন হয় তবে দ্রুততম উপায়টি হ'ল একটি listপূর্ণসংখ্যাটি ধরে রাখা এবং একটি স্টিক[0] উপায়টি হ'ল এটির প্রতিটি ব্যবহারকে প্রায় , যেমন মিলিগ্রামের উত্তরটি দেখায়।

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

আরও সাধারণভাবে, আপনি যদি কিছু জাভা আইডিয়োম সরাসরি পাইথনে বন্দর করার চেষ্টা করছেন তবে আপনি এটি ভুল করছেন। এমনকি যখন সরাসরি সম্পর্কিত কিছু আছে (যেমন static/ / তেমন @staticmethod), আপনি এখনও এটি জাভাতে ব্যবহার করার কারণে বেশিরভাগ পাইথন প্রোগ্রামগুলিতে এটি ব্যবহার করতে চান না।


জাভা রেফারেন্স দ্বারা পূর্ণসংখ্যার পাস করে না (পূর্ণসংখ্যা বা কোনও বস্তু box বাক্সযুক্ত বস্তুগুলি নিয়োগের পরেও প্রতিস্থাপন করা হয়)।
লুইস মাসুয়েলি

@ লুইসম্যাসুয়েলি ওয়েল, বাক্সযুক্ত প্রিমিটগুলি ঠিক বস্তুর মতোই ব্যবহার করা হয়, ওপি যেমন চায় তাদের ব্যবহার প্রতিরোধ করার বিষয়টি কেবল বাক্সগুলি অপরিবর্তনীয় (এবং যেহেতু আদিমরা নিজেও অপরিবর্তনীয়, পুরো জিনিসটি পরিবর্তনযোগ্য এবং কেবলমাত্র এখানে পরিবর্তন করা যেতে পারে) পরিবর্তনশীল স্তর)
Kroltan

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

4

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

যেহেতু আপনি আপনার প্রশ্নে জাভা উল্লেখ করেছেন, তাই আমি জাভাতে আপনি কী চান তা কীভাবে অর্জন করেন তা দেখতে চাই। আপনি যদি এটি জাভাতে দেখাতে পারেন, আমি আপনাকে পাইথন-তে ঠিক কীভাবে এটি করতে হবে তা আপনাকে দেখাতে পারি।


4

একটি অদ্ভুত একক-উপাদান অ্যারে পরিবর্তনীয় এবং এখনও বেশিরভাগ উদ্দেশ্যে, এটি মূল্যায়ন করা যেতে পারে যেমন এটি একটি সংখ্যক পাইথন পরিবর্তনশীল। সুতরাং, এটি একটি একক-উপাদান তালিকার চেয়ে আরও বেশি সুবিধাজনক বাই-রেফারেন্স নম্বর ধারক।

    import numpy as np
    def triple_var_by_ref(x):
        x[0]=x[0]*3
    a=np.array([2])
    triple_var_by_ref(a)
    print(a+1)

আউটপুট:

3


3

সম্ভবত এটি অজগর উপায় নয়, তবে আপনি এটি করতে পারেন

import ctypes

def incr(a):
    a += 1

x = ctypes.c_int(1) # create c-var
incr(ctypes.ctypes.byref(x)) # passing by ref

মানুষ যে স্মার্ট।
xilpex

2

তালিকা-দৈর্ঘ্যের -1 ট্রিকের চেয়ে কিছুটা বেশি স্ব-ডকুমেন্টিং হ'ল পুরাতন খালি টাইপের কৌশল:

def inc_i(v):
    v.i += 1

x = type('', (), {})()
x.i = 7
inc_i(x)
print(x.i)

: অথবা কোন ক্লাসে সংখ্যা মোড়ানো github.com/markrages/python_mutable_number
markrages

0

পাইথনে, সমস্ত কিছু মান দ্বারা পাস হয় তবে আপনি যদি কিছু স্থিতি সংশোধন করতে চান তবে আপনি কোনও পদ্ধতিতে পাস হওয়া তালিকা বা বস্তুর অভ্যন্তরের পূর্ণসংখ্যার মান পরিবর্তন করতে পারেন।


4
আমি মনে করি, কারণ everything is passed by valueএটি সত্য নয়। উদ্ধৃতি দস্তাবেজ:arguments are passed using call by value (where the value is always an object reference, not the value of the object)
Astery

4
তালিকা, অবজেক্টস এবং
অভিধানগুলি

4
যদি এটি সত্য হয় তবে কোনও ফাংশনে একটি প্যারামিটারে অ্যাসাইনমেন্ট কল সাইটে প্রদর্শিত হবে। Astery যেমন উদ্ধৃত হয় মান দ্বারা হয় এবং সেই মানগুলি অবজেক্ট রেফারেন্স হয়।
পুনরাবৃত্তি

0

সঠিক উত্তরটি হ'ল একটি ক্লাস ব্যবহার করা এবং ক্লাসের মধ্যে মান স্থাপন করা, এটি আপনাকে যেমন ইচ্ছা তেমন রেফারেন্স দিয়ে পাস করতে দেয়।

class Thing:
  def __init__(self,a):
    self.a = a
def dosomething(ref)
  ref.a += 1

t = Thing(3)
dosomething(t)
print("T is now",t.a)

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