යොමු අනුව විචල්‍යයක් සම්මත කරන්නේ කෙසේද?


2639

පරාමිතීන් යොමු හෝ අගය අනුව සම්මත වී ඇත්ද යන්න පිළිබඳව පයිතන් ප්‍රලේඛනය අපැහැදිලි වන අතර පහත කේතය වෙනස් නොවන 'ඔරිජිනල්' අගය නිපදවයි.

class PassByReference:
    def __init__(self):
        self.variable = 'Original'
        self.change(self.variable)
        print(self.variable)

    def change(self, var):
        var = 'Changed'

සත්‍ය යොමු කිරීම මගින් විචල්‍යය සම්මත කිරීමට මට කළ හැකි යමක් තිබේද?


23
කෙටි පැහැදිලි කිරීමක් / පැහැදිලි කිරීමක් සඳහා මෙම ස්ටක් ඕවර් ප්‍රවාහ ප්‍රශ්නයට පළමු පිළිතුර බලන්න . නූල් වෙනස් කළ නොහැකි බැවින් ඒවා වෙනස් නොවන අතර නව විචල්‍යයක් නිර්මාණය වනු ඇත, එබැවින් "පිටත" විචල්‍යයට තවමත් එකම අගයක් ඇත.
ෆිල්ස්

10
බ්ලෙයාර්කොන්රාඩ්ගේ පිළිතුරේ කේතය හොඳයි, නමුත් ඩේවිඩ් කෝර්නපියෝ සහ ඩැරන් තෝමස් විසින් සපයන ලද පැහැදිලි කිරීම නිවැරදි ය.
ඊතන් ෆුරමන්

70
තෝරාගත් පිළිතුර කියවීමට පෙර කරුණාකර මෙම කෙටි පා reading ය කියවීම සලකා බලන්න වෙනත් භාෂාවන්ට “විචල්‍යයන්” ඇත, පයිතන්ට “නම්” ඇත. "විචල්යයන්" සහ "යොමු කිරීම්" වෙනුවට "නම්" සහ "වස්තූන්" ගැන සිතන්න, ඔබ සමාන ගැටළු රාශියක් වළක්වා ගත යුතුය.
lqc

24
මෙය අනවශ්‍ය ලෙස පන්තියක් භාවිතා කරන්නේ ඇයි? මෙය ජාවා නොවේ: පී
පීටර් ආර්

2
තවත් කාර්යයක් නම්, මේ ආකාරයට එතීෙම් 'යොමු කිරීමක්' නිර්මාණය කිරීමයි: ref = type ('', (), {'n': 1}) stackoverflow.com/a/1123054/409638
robert

Answers:


2849

පැවරුම් මගින් තර්ක සම්මත කරනු ලැබේ . මේ පිටුපස ඇති තාර්කිකත්වය දෙයාකාර ය:

  1. සම්මත කළ පරාමිතිය ඇත්ත වශයෙන්ම වස්තුවකට යොමු කිරීමකි (නමුත් යොමු කිරීම අගය අනුව සම්මත වේ)
  2. සමහර දත්ත වර්ග විකෘති වන නමුත් අනෙක් ඒවා එසේ නොවේ

නිසා:

  • ඔබ විකෘති වස්තුවක් ක්‍රමයකට යොමු කළහොත්, එම ක්‍රමයට එම වස්තුවටම යොමු කිරීමක් ලැබෙන අතර ඔබට එය ඔබේ හදවතේ ප්‍රීතියට විකෘති කළ හැකිය, නමුත් ඔබ එම ක්‍රමවේදය නැවත යොමු කළහොත් පිටත විෂය පථය ඒ ගැන කිසිවක් නොදන්නා අතර පසුව ඔබ ඉවරයි, පිටත යොමුව තවමත් මුල් වස්තුව වෙත යොමු වේ.

  • ඔබ වෙනස් කළ නොහැකි වස්තුවක් ක්‍රමයකට යොමු කළහොත්, ඔබට තවමත් බාහිර යොමු කිරීම නැවත කළ නොහැකි අතර, ඔබට වස්තුව විකෘති කිරීමට පවා නොහැකිය.

එය වඩාත් පැහැදිලි කිරීම සඳහා, අපි උදාහරණ කිහිපයක් බලමු.

ලැයිස්තුව - විකෘති වර්ගයකි

ක්‍රමයකට සම්මත කළ ලැයිස්තුව වෙනස් කිරීමට උත්සාහ කරමු:

def try_to_change_list_contents(the_list):
    print('got', the_list)
    the_list.append('four')
    print('changed to', the_list)

outer_list = ['one', 'two', 'three']

print('before, outer_list =', outer_list)
try_to_change_list_contents(outer_list)
print('after, outer_list =', outer_list)

ප්‍රතිදානය:

before, outer_list = ['one', 'two', 'three']
got ['one', 'two', 'three']
changed to ['one', 'two', 'three', 'four']
after, outer_list = ['one', 'two', 'three', 'four']

සම්මත කරන ලද පරාමිතිය outer_listඑහි පිටපතක් නොව යොමු කිරීමක් බැවින් අපට එය වෙනස් කිරීමට විකෘති ලැයිස්තු ක්‍රම භාවිතා කළ හැකි අතර බාහිර විෂය පථයේ වෙනස්කම් පිළිබිඹු වේ.

දැන් අපි පරාමිතියක් ලෙස සම්මත කළ යොමුව වෙනස් කිරීමට උත්සාහ කළ විට කුමක් සිදුවේදැයි බලමු:

def try_to_change_list_reference(the_list):
    print('got', the_list)
    the_list = ['and', 'we', 'can', 'not', 'lie']
    print('set to', the_list)

outer_list = ['we', 'like', 'proper', 'English']

print('before, outer_list =', outer_list)
try_to_change_list_reference(outer_list)
print('after, outer_list =', outer_list)

ප්‍රතිදානය:

before, outer_list = ['we', 'like', 'proper', 'English']
got ['we', 'like', 'proper', 'English']
set to ['and', 'we', 'can', 'not', 'lie']
after, outer_list = ['we', 'like', 'proper', 'English']

the_listපරාමිතිය අගය අනුව සම්මත කර ඇති හෙයින් , එයට නව ලැයිස්තුවක් පැවරීමෙන් ක්‍රමයට පිටතින් ඇති කේතයට කිසිදු බලපෑමක් සිදු නොවීය. මෙම the_listකරන පිටපතක් විය outer_listසඳහනක්, සහ අප සිදු the_listනව ලැයිස්තුවට අවස්ථාවක, නමුත් එහිදී වෙනස් කිරීමට ක්රමයක් තිබුණේ නැහැ outer_listඋල්.

නූල් - වෙනස් කළ නොහැකි වර්ගයකි

එය වෙනස් කළ නොහැකි බැවින් නූල් වල අන්තර්ගතය වෙනස් කිරීමට අපට කළ හැකි කිසිවක් නැත

දැන්, යොමු කිරීම වෙනස් කිරීමට උත්සාහ කරමු

def try_to_change_string_reference(the_string):
    print('got', the_string)
    the_string = 'In a kingdom by the sea'
    print('set to', the_string)

outer_string = 'It was many and many a year ago'

print('before, outer_string =', outer_string)
try_to_change_string_reference(outer_string)
print('after, outer_string =', outer_string)

ප්‍රතිදානය:

before, outer_string = It was many and many a year ago
got It was many and many a year ago
set to In a kingdom by the sea
after, outer_string = It was many and many a year ago

නැවතත්, the_stringපරාමිතිය අගය මගින් සම්මත කර ඇති හෙයින් , එයට නව නූලක් පැවරීමෙන් ක්‍රමයට පිටතින් ඇති කේතයට කිසිදු බලපෑමක් සිදු නොවීය. මෙම the_stringකරන පිටපතක් විය outer_stringසඳහනක්, සහ අප සිදු the_stringනව සංගීත යොමුකර, නමුත් එහිදී වෙනස් කිරීමට ක්රමයක් තිබුණේ නැහැ outer_stringඋල්.

මම හිතනවා මේකෙන් දේවල් ටිකක් පිරිසිදු වේවි කියලා.

සංස්කරණය කරන්න: ඩේවිඩ් මුලින් ඇසූ ප්‍රශ්නයට මෙය පිළිතුරු නොදෙන බව සටහන් කර ඇත, "සත්‍ය යොමු කිරීම මගින් විචල්‍යය සමත් කිරීමට මට යමක් කළ හැකිද?". අපි ඒ ගැන වැඩ කරමු.

අපි කොහොමද මේකෙන් බේරෙන්නේ?

@ ඇන්ඩ්‍රියාගේ පිළිතුරෙන් පෙන්නුම් කරන පරිදි, ඔබට නව අගය ආපසු ලබා දිය හැකිය. මෙය දේවල් සම්මත කර ගන්නා ආකාරය වෙනස් නොකරයි, නමුත් ඔබට අවශ්‍ය තොරතුරු ආපසු ලබා ගැනීමට ඉඩ දෙයි:

def return_a_whole_new_string(the_string):
    new_string = something_to_do_with_the_old_string(the_string)
    return new_string

# then you could call it like
my_string = return_a_whole_new_string(my_string)

ප්‍රතිලාභ අගයක් භාවිතා කිරීමෙන් වැළකී සිටීමට ඔබට සැබවින්ම අවශ්‍ය නම්, ඔබේ අගය රඳවා තබාගෙන එය ශ්‍රිතයට ඇතුළත් කිරීමට හෝ ලැයිස්තුවක් වැනි පවතින පන්තියක් භාවිතා කිරීමට ඔබට පන්තියක් නිර්මාණය කළ හැකිය:

def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change):
    new_string = something_to_do_with_the_old_string(stuff_to_change[0])
    stuff_to_change[0] = new_string

# then you could call it like
wrapper = [my_string]
use_a_wrapper_to_simulate_pass_by_reference(wrapper)

do_something_with(wrapper[0])

මෙය ටිකක් කරදරකාරී බවක් පෙනුනත්.


166
C හි ද එයම වේ, ඔබ "යොමු කිරීමෙන්" සමත් වූ විට ඔබ සැබවින්ම යොමු කිරීම අගය අනුව ගමන් කරයි ... "යොමුව අනුව" යන්න අර්ථ දක්වන්න: P
Andrea Ambu

106
ඔබේ කොන්දේසි මට තේරෙන බව මට විශ්වාස නැත. මම ටික කලක් සී ක්‍රීඩාවෙන් ඉවත් වී සිටිමි, නමුත් මම එහි සිටින විට "යොමු කිරීම හරහා ගමන් කිරීමක්" නොතිබුණි - ඔබට දේවල් සමත් විය හැකි අතර එය සැමවිටම අගය අනුව සම්මත විය, එබැවින් පරාමිති ලැයිස්තුවේ ඇති ඕනෑම දෙයක් පිටපත් කරන ලදි. නමුත් සමහර විට එය මතකය (ප්‍රාථමික, අරාව, ව්‍යුහය, කුමක් වුවත්) අනුගමනය කළ හැකි දර්ශකයක් විය, නමුත් පිටත විෂය පථයෙන් පිටපත් කළ දර්ශකය ඔබට වෙනස් කළ නොහැක - ඔබ ශ්‍රිතය අවසන් කළ විට , මුල් දර්ශකය තවමත් එකම ලිපිනයට යොමු කර ඇත. සී ++ වෙනස් ලෙස හැසිරුණු යොමු කිරීම් හඳුන්වා දුන්නේය.
බ්ලෙයාර් කොන්රාඩ්

35
Ac සැක් පන්දු යැවීම ප්‍රායෝගික අර්ථයෙන් මෙම පිළිතුරට අදාළ වන්නේ කෙසේදැයි මට තේරෙන්නේ නැත. උත්කර්ෂවත් අන්දමින් අලුතින්ද ref / Val ළඟින් ගැන දැන ගැනීමට අවශ්ය නම්, මෙම පිළිතුර සිට කෝප්පත් වේ: 1- ඔබ හැකි තාක්, විචල්ය වන 'පිටත' අගය වෙනස් කිරීමට, විශාල උත්සවයක් සිය තර්ක ලෙස ලැබෙන බව සඳහන් භාවිතා නව වස්තුවක් වෙත යොමු කිරීම සඳහා ඔබ පරාමිතිය නැවත පවරා නොදෙන බැවින්. 2- වෙනස් කළ නොහැකි වර්ගයකට පැවරීම සෑම විටම නව වස්තුවක් නිර්මාණය කරනු ඇත , එමඟින් ඔබ බාහිර විචල්‍යයට කළ සඳහන බිඳ දමයි.
කැම් ජැක්සන්

11
Am කැම් ජැක්සන්, ඔබට මීට වඩා හොඳ උදාහරණයක් අවශ්‍යයි - ඉලක්කම් ද පයිතන්හි වෙනස් කළ නොහැකි වස්තු වේ. ඊට අමතරව, සමාන වම් පසින් දායක නොවී ඕනෑම පැවරුමක් නව වස්තුවකට වෙනස් කළ නොහැකි වුවත් නැතත් එය නැවත පවරනු ඇතැයි පැවසීම සත්‍යයක් නොවේද? def Foo(alist): alist = [1,2,3]ඇත නැත , අමතන්නාට ඉදිරිදර්ශනය සිට ලැයිස්තුව අන්තර්ගතය වෙනස්.
මාර්ක් රැන්සම්

59
-1. පෙන්වා ඇති කේතය හොඳයි, සම්පූර්ණයෙන්ම වැරදි වන්නේ කෙසේද යන්න පැහැදිලි කිරීම. එයට හේතුව පිළිබඳ නිවැරදි පැහැදිලි කිරීම් සඳහා ඩේවිඩ් කෝර්නපියෝ හෝ ඩැරන් තෝමස්ගේ පිළිතුරු බලන්න.
ඊතන් ෆුරමන්

690

ගැටළුව පැමිණෙන්නේ පයිතන්හි ඇති විචල්‍යයන් මොනවාද යන්න පිළිබඳ වැරදි වැටහීමකිනි. ඔබ බොහෝ සාම්ප්‍රදායික භාෂාවන්ට පුරුදු වී සිටින්නේ නම්, පහත දැක්වෙන අනුපිළිවෙලෙහි කුමක් සිදුවේද යන්න පිළිබඳ මානසික ආකෘතියක් ඔබට ඇත:

a = 1
a = 2

aඑය අගය ගබඩා කරන මතක ස්ථානයක් බව ඔබ විශ්වාස කරයි 1, පසුව අගය ගබඩා කිරීම සඳහා යාවත්කාලීන වේ 2. පයිතන් වල දේවල් ක්‍රියා කරන්නේ එලෙස නොවේ. ඒ වෙනුවට, aඅගය සහිත වස්තුවක් සඳහා යොමු කිරීමක් ලෙස ආරම්භ වන අතර 1, පසුව අගය සහිත වස්තුවක් වෙත යොමු කිරීමක් ලෙස නැවත පැවරේ 2. පළමු වස්තුව ගැන තවදුරටත් සඳහන් නොකලත් එම වස්තූන් දෙක දිගටම සහජීවනයෙන් සිටිය හැකිය a; ඇත්ත වශයෙන්ම ඒවා වැඩසටහන තුළ ඇති වෙනත් යොමු කිරීම් ගණනාවකින් බෙදා ගත හැකිය.

ඔබ පරාමිතියක් සහිත ශ්‍රිතයක් අමතන විට, සම්මත කරන ලද වස්තුවට යොමු වන නව යොමු කිරීමක් සාදනු ලැබේ. මෙය ශ්‍රිත ඇමතුමෙහි භාවිතා කළ යොමුවලින් වෙන්ව ඇත, එබැවින් එම යොමු කිරීම යාවත්කාලීන කර එය යොමු කිරීමට ක්‍රමයක් නොමැත නව වස්තුව. ඔබේ උදාහරණයේ:

def __init__(self):
    self.variable = 'Original'
    self.Change(self.variable)

def Change(self, var):
    var = 'Changed'

self.variableයනු නූල් වස්තුවට යොමු කිරීමකි 'Original'. ඔබ අමතන විට ඔබ වස්තුවට Changeදෙවන යොමු varකිරීමක් සාදයි. ශ්‍රිතය ඇතුළත ඔබ නැවත යොමු කිරීමvar කිරීම වෙනත් සංගීත වස්තුවකට'Changed' , නමුත් යොමුව self.variableවෙනම වන අතර වෙනස් නොවේ.

මේ සඳහා ඇති එකම ක්‍රමය වන්නේ විකෘති වස්තුවක් පසු කිරීමයි. යොමු දෙකම එකම වස්තුවකට යොමු වන හෙයින්, වස්තුවෙහි කිසියම් වෙනස්කමක් ස්ථාන දෙකෙහිම පිළිබිඹු වේ.

def __init__(self):         
    self.variable = ['Original']
    self.Change(self.variable)

def Change(self, var):
    var[0] = 'Changed'

107
හොඳ සංක්ෂිප්ත පැහැදිලි කිරීමක්. ඔබේ ඡේදය "ඔබ ශ්‍රිතයක් අමතන විට ..." යනු 'පයිතන් ශ්‍රිත පරාමිතීන් යොමු කිරීම්, අගය අනුව සම්මත කිරීම' යන තරමක් ගුප්ත වාක්‍ය ඛණ්ඩය ගැන මා අසා ඇති හොඳම පැහැදිලි කිරීමකි. මම හිතන්නේ ඔබ එම ඡේදය පමණක් තේරුම් ගත්තා නම්, අනෙක් සෑම දෙයක්ම අර්ථවත් වන අතර එතැන් සිට තාර්කික නිගමනයක් ලෙස ගලා යයි. ඔබ නව වස්තුවක් නිර්මාණය කරන විට සහ පවතින එකක් වෙනස් කරන විට ඔබ දැනුවත් විය යුතුය.
කැම් ජැක්සන්

3
නමුත් ඔබට එය නැවත පැවරිය හැක්කේ කෙසේද? මම සිතුවේ ඔබට 'var' හි ලිපිනය වෙනස් කළ නොහැකි නමුත් ඔබේ "වෙනස් කරන ලද" නූල දැන් 'var' මතක ලිපිනයේ ගබඩා වනු ඇති බවයි. ඔබගේ විස්තරය එය "වෙනස් කරන ලද" සහ "මුල්" මතකයේ විවිධ ස්ථාන වලට අයත් බව පෙනේ, ඔබ 'var' වෙනත් ලිපිනයකට මාරු කරයි. ඒක හරිද?
ග්ලාස්ජාවෙඩ්

9
@ ග්ලාස්ජාවෙඩ්, මම හිතන්නේ ඔබ එය ලබා ගත්තා. "වෙනස් කරන ලද" සහ "මුල්" යනු විවිධ මතක ලිපිනවල ඇති විවිධ නූල් වස්තු දෙකක් වන අතර 'var' වෙනස් වන්නේ එකක් සිට අනෙක් දෙසට යොමු කිරීමෙනි.
මාර්ක් රැන්සම්

id () ශ්‍රිතය භාවිතා කිරීම කාරණා පැහැදිලි කිරීමට උපකාරී වේ, මන්ද එය පයිතන් නව වස්තුවක් නිර්මාණය කරන විට එය පැහැදිලි කරයි (එබැවින් මම කෙසේ හෝ සිතමි).
ටිම් රිචඩ්සන්

1
In මිංට්‍රාන් සරළව කිවහොත්, යොමු කිරීමක් යනු වස්තුවකට “යොමු” වන දෙයකි. එහි භෞතික නිරූපණය බොහෝ දුරට දර්ශකයක් විය හැකි නමුත් එය හුදෙක් ක්‍රියාත්මක කිරීමේ විස්තරයකි. එය සැබවින්ම හදවතේ වියුක්ත සංකල්පයකි.
මාර්ක් රැන්සම්

330

අනෙක් පිළිතුරු තරමක් දිගු හා සංකීර්ණ බව මට පෙනී ගියේය, එබැවින් පයිතන් විචල්යයන් සහ පරාමිතීන් සලකන ආකාරය පැහැදිලි කිරීම සඳහා මම මෙම සරල රූප සටහන නිර්මාණය කළෙමි. රූප විස්තරය මෙහි ඇතුළත් කරන්න


2
සුන්දර, අතරමැදි පැවරුමක් ඇති බව සියුම් වෙනස හඳුනා ගැනීම පහසු කරයි, අනියම් නිරීක්ෂකයෙකුට එය පැහැදිලි නැත. +1
user22866

9
A විකෘතිද නැද්ද යන්න ගැටළුවක් නොවේ. ඔබ B ට වෙනස් දෙයක් පවරන්නේ නම්, A වෙනස් නොවේ . වස්තුවක් විකෘති නම්, ඔබට එය විකෘති කළ හැකිය, විශ්වාසයි. නමුත් එයට සෘජුවම නමකට පැවරීම සමග කිසිදු සම්බන්ධයක් නැත ..
මාර්ටිජ් පීටර්ස්

1
Ar මාටිජන් ඔබ හරි. විකෘතිතාව සඳහන් කරන පිළිතුරේ කොටස මම ඉවත් කළෙමි. මම හිතන්නේ නැහැ දැන් එය වඩාත් සරල කර ගත හැකිය.
සෙනඩික්ස්

4
යාවත්කාලීන කිරීමට ස්තූතියි, වඩා හොඳය! බොහෝ අය ව්‍යාකූල වන්නේ දායකත්වයට පැවරීම ය; උදා: B[0] = 2එදිරිව සෘජු පැවරුම , B = 2.
මාර්ටිජන් පීටර්ස්

11
"A ට අනුයුක්ත කර ඇත." එය අපැහැදිලි නොවේ ද? මම හිතන්නේ සාමාන්‍ය ඉංග්‍රීසියෙන් A=Bහෝ එයින් අදහස් විය හැකිය B=A.
හට්ෂෙප්සුට්

241

එය පසු-අගය හෝ පසු-යොමු-යොමු කිරීමක් නොවේ - එය ඇමතුමකින් වස්තුවකි. ෆ්‍රෙඩ්රික් ලුන්ඩ් විසින් මෙය බලන්න:

http://effbot.org/zone/call-by-object.htm

මෙන්න වැදගත් උපුටා දැක්වීමක්:

"... විචල්යයන් [නම්] වස්තූන් නොවේ ; ඒවා වෙනත් විචල්යයන් මගින් දැක්විය නොහැක.

ඔබේ උදාහරණයේ දී, Changeක්‍රමය හැඳින්වූ විට - ඒ සඳහා නාම අවකාශයක් නිර්මාණය වේ; සහ varඑම නාම අවකාශය තුළ, නූල් වස්තුව සඳහා නමක් බවට පත්වේ 'Original'. එම වස්තුවට නාම අවකාශ දෙකක නමක් ඇත. ඊළඟට, නව නූල් වස්තුවකට var = 'Changed'බන්ධනය varවන අතර එමඟින් ක්‍රමයේ නාම අවකාශය අමතක 'Original'වේ. අවසාන වශයෙන්, එම නාම අවකාශය අමතක වන අතර, ඒ සමඟම නූල් 'Changed'.


21
මට මිලදී ගැනීමට අපහසුය. මට නම් ජාවා මෙන්, පරාමිතීන් මතකයේ ඇති වස්තූන් වෙත යොමු වන අතර, එම දර්ශකයන් තොගය හරහා හෝ රෙජිස්ටර් හරහා යවනු ලැබේ.
ලුසියානෝ

10
මෙය ජාවා මෙන් නොවේ. එය එක හා සමාන නොවන එක් අවස්ථාවක් වන්නේ වෙනස් කළ නොහැකි වස්තූන් ය. ලැම්බඩා x: x යන සුළු ක්‍රියාකාරිත්වය ගැන සිතන්න. X = [1, 2, 3] සහ x = (1, 2, 3) සඳහා මෙය යොදන්න. පළමු අවස්ථාවෙහිදී, ආපසු ලබා දුන් අගය ආදානයේ පිටපතක් වන අතර දෙවන අවස්ථාවෙහිදී සමාන වේ.
ඩේවිඩ් කෝර්නපියෝ

26
නැත, එය හරියටම ජාවා වස්තූන් සඳහා අර්ථ නිරූපණයට සමානය. "පළමු අවස්ථාවේ දී, ආපසු ලබා දුන් අගය ආදානයේ පිටපතක් වනු ඇති අතර දෙවන අවස්ථාවෙහිදී සමාන වේ" යනුවෙන් ඔබ අදහස් කරන්නේ කුමක්දැයි මට විශ්වාස නැත. නමුත් එම ප්‍රකාශය පැහැදිලිවම වැරදිය.
මයික් ග්‍රැහැම්

23
එය ජාවාහි මෙන් ම සමාන ය. වස්තු යොමු කිරීම් අගය අනුව සම්මත වේ. වෙනස් ලෙස සිතන ඕනෑම අයෙකු මේ swapහා සමාන යොමු දෙකක් මාරු කළ හැකි ශ්‍රිතයක් සඳහා පයිතන් කේතය අමුණන්න : a = [42] ; b = 'Hello'; swap(a, b) # Now a is 'Hello', b is [42]
cayhorstmann

24
ඔබ ජාවා හි වස්තූන් පසු කරන විට එය හරියටම ජාවා හා සමාන වේ. කෙසේ වෙතත්, ජාවාහි ද ප්‍රාථමිකයන් ඇත, ඒවා ප්‍රාථමිකයේ අගය පිටපත් කිරීමෙන් සම්මත වේ. මේ අනුව ඔවුන් එම අවස්ථාවේ දී වෙනස් වේ.
ක්ලෝඩියු

176

පැවරුම් මගින් සම්මත කරන දේවල් ගැන සිතන්නයොමු කිරීම / අගය අනුව නොව . සාමාන්‍ය පැවරුමේදී සිදුවන්නේ කුමක්ද යන්න ඔබ තේරුම් ගන්නා තාක් කල් සිදුවන්නේ කුමක්ද යන්න සෑම විටම පැහැදිලිය.

එබැවින්, ලැයිස්තුවක් ශ්‍රිතයකට / ක්‍රමයකට යොමු කරන විට, ලැයිස්තුව පරාමිති නාමයට පවරනු ලැබේ. ලැයිස්තුවට එකතු කිරීමෙන් ලැයිස්තුව වෙනස් කරනු ලැබේ. ශ්‍රිතය තුළ ලැයිස්තුව නැවත පැවරීමෙන් මුල් ලැයිස්තුව වෙනස් නොවේ, මන්ද:

a = [1, 2, 3]
b = a
b.append(4)
b = ['a', 'b']
print a, b      # prints [1, 2, 3, 4] ['a', 'b']

වෙනස් කළ නොහැකි වර්ග වෙනස් කළ නොහැකි බැවින්, ඒවා අගය අනුව සම්මත වී ඇති බවක් පෙනේ - ශ්‍රිතයක් තුළට int එකක් යැවීම යනු ශ්‍රිතයේ පරාමිතියට int ලබා දීමයි. ඔබට එය නැවත පැවරිය හැක්කේ එය පමණි, නමුත් එය මුල් විචල්‍යයන්ගේ අගය වෙනස් නොකරයි.


3
බැලූ බැල්මට මෙම පිළිතුර මුල් ප්‍රශ්නය පැත්තකට හරවන බවක් පෙනේ. තත්පර කියවීමකින් පසුව මට වැටහී ඇත්තේ මෙය කාරණය පැහැදිලි කරන බවයි. මෙම "නාම පැවරුම" සංකල්පය පිළිබඳ හොඳ පසු විපරමක් මෙහි සොයාගත හැකිය : පයිතොනිස්ටා වැනි කේතය: අයිඩියොමැටික් පයිතන්
ක්‍රිස්ටියන් ග්‍රෝලියෝ

67

පයිතන්ගේ විචල්‍ය ගමන් විලාසය ඇමතුම්-වස්තුවක් ලෙස එෆ්බොට් (ෆ්‍රෙඩ්රික් ලුන්ඩ්) විස්තර කර ඇත: http://effbot.org/zone/call-by-object.htm

ගොඩවල් මත වස්තූන් වෙන් කර ඇති අතර ඒවාට යොමු කරන්නන් ඕනෑම තැනක සම්මත කළ හැකිය.

  • ඔබ වැනි පැවරුමක් සිදු කරන විට x = 1000, ශබ්ද කෝෂ ඇතුළත් කිරීමක් සාදනු ලබන අතර එය වත්මන් නාම අවකාශයේ “x” නූල දහසක් අඩංගු පූර්ණ සංඛ්‍යා වස්තුවට යොමු කරයි.

  • ඔබ "x" සමඟ යාවත්කාලීන කරන විට x = 2000, නව පූර්ණ සංඛ්‍යා වස්තුවක් නිර්මාණය වන අතර නව වස්තුව වෙත යොමු කිරීම සඳහා ශබ්ද කෝෂය යාවත්කාලීන වේ. පැරණි දහසක් වස්තුව නොවෙනස්ව පවතී (සහ වෙනත් දෙයක් වස්තුවට යොමු වන්නේද යන්න මත පදනම්ව ජීවමාන විය හැකිය).

  • ඔබ වැනි නව පැවරුමක් කරන විට y = x, "x" සඳහා වන ප්‍රවේශයට සමාන වස්තුවකට යොමු වන නව ශබ්දකෝෂ ප්‍රවේශයක් "y" සාදනු ලැබේ.

  • නූල් සහ නිඛිල වැනි වස්තූන් වෙනස් කළ නොහැක. මෙයින් සරලවම අදහස් වන්නේ වස්තුව නිර්මාණය කිරීමෙන් පසු එය වෙනස් කළ හැකි ක්‍රම නොමැති බවයි. උදාහරණයක් ලෙස, පූර්ණ සංඛ්‍යා වස්තුව දහසක් නිර්මාණය කළ පසු එය කිසි විටෙකත් වෙනස් නොවේ. ගණිතය සිදු කරනුයේ නව පූර්ණ සංඛ්‍යා වස්තු නිර්මාණය කිරීමෙනි.

  • ලැයිස්තු වැනි වස්තු විකෘති වේ. මෙයින් අදහස් කරන්නේ වස්තුවට යොමු වන ඕනෑම දෙයකින් වස්තුවේ අන්තර්ගතය වෙනස් කළ හැකි බවයි. උදාහරණයක් ලෙස, x = []; y = x; x.append(10); print yමුද්‍රණය කරනු ඇත [10]. හිස් ලැයිස්තුව නිර්මාණය කරන ලදි. "X" සහ "y" යන දෙකම එකම ලැයිස්තුවට යොමු කරයි. මෙම ඇතුලත් ක්රමය වෙසන් (යාවත්කාලීන) ලැයිස්තුව වස්තුව (අ දත්ත සමුදාය වාර්තා එකතු වැනි) එහි ප්රතිඵලය "X" සහ (දත්ත සමුදා යාවත් කාලීන කිරීම දත්ත සමුදාය සඳහා සෑම සම්බන්ධයක් දැක ගත හැකි වනු ඇත සේම) "y" යන දැකගත හැක.

ඔබ වෙනුවෙන් ගැටලුව පැහැදිලි කරන බලාපොරොත්තුව.


3
සංවර්ධකයෙකුගෙන් මේ ගැන ඉගෙන ගැනීම මම අගය කරමි. id()ගම්මිරිස්ගේ පිළිතුරෙන් දැක්වෙන පරිදි , ශ්‍රිතය මඟින් දර්ශකයේ (වස්තු යොමු) අගය ලබා දෙන බව සත්‍යයක් ද?
අවංක අබේ

4
OnHonestAbe ඔව්, CPython හි හැඳුනුම්පත () ලිපිනය ලබා දෙයි. නමුත් PyPy සහ Jython වැනි වෙනත් පයිතන් වල, id () යනු අද්විතීය වස්තු හඳුනාගැනීමක් පමණි.
රේමන්ඩ් හෙටින්ගර්

61

තාක්ෂණික වශයෙන්, පයිතන් සෑම විටම පාස් මගින් යොමු අගයන් භාවිතා කරයි . මගේ ප්‍රකාශයට සහය දැක්වීම සඳහා මම මගේ අනෙක් පිළිතුර නැවත කියමි .

පයිතන් සැමවිටම පාස්-බයි-යොමු අගයන් භාවිතා කරයි. ව්යතිරේකයක් නොමැත. ඕනෑම විචල්‍ය පැවරුමක් යනු යොමු අගය පිටපත් කිරීමයි. ව්යතිරේකයක් නැත. ඕනෑම විචල්‍යයක් යනු විමර්ශන අගයට බැඳී ඇති නමයි. සැමවිටම.

ඉලක්කගත වස්තුවේ ලිපිනය ලෙස ඔබට විමර්ශන අගයක් ගැන සිතිය හැකිය. භාවිතා කරන විට ලිපිනය ස්වයංක්‍රීයව අවලංගු වේ. මේ ආකාරයෙන්, යොමු අගය සමඟ වැඩ කරන විට, ඔබ ඉලක්කගත වස්තුව සමඟ කෙලින්ම වැඩ කරන බව පෙනේ. නමුත් සෑම විටම ඉලක්කයක් කරා යාමට තවත් එක් පියවරක් ඇත.

පයිතන් යොමු කිරීම මඟින් භාවිතා කරන බව සනාථ කරන උදාහරණය මෙන්න:

තර්කය සම්මත කිරීම පිළිබඳ නිදර්ශන උදාහරණය

තර්කය අගය අනුව සම්මත කර ඇත්නම්, පිටත lstවෙනස් කළ නොහැක. කොළ යනු ඉලක්කගත වස්තූන්ය (කළු යනු ඇතුළත ගබඩා කර ඇති අගයයි, රතු යනු වස්තු වර්ගයයි), කහ යනු ඇතුළත යොමු අගය සහිත මතකයයි - ඊතලය ලෙස අඳින්න. නිල් solid න ඊතලය යනු ශ්‍රිතයට යොමු කරන ලද යොමු අගයයි (ඉරුණු නිල් ඊතල මාර්ගය හරහා). කැත තද කහ යනු අභ්‍යන්තර ශබ්දකෝෂයයි. (ඇත්ත වශයෙන්ම එය හරිත ඉලිප්සයක් ලෙසද ඇද ගත හැකිය. වර්ණය හා හැඩය පවසන්නේ එය අභ්‍යන්තරයයි.)

id()විමර්ශන අගය යනු කුමක්දැයි දැන ගැනීමට ඔබට බිල්ට් ශ්‍රිතය භාවිතා කළ හැකිය (එනම් ඉලක්කගත වස්තුවේ ලිපිනය).

සම්පාදනය කරන ලද භාෂාවලින්, විචල්‍යයක් යනු මතක අවකාශයක් වන අතර එය වර්ගයේ අගය ග්‍රහණය කර ගත හැකිය. පයිතන්හි, විචල්‍යය යනු ඉලක්කගත වස්තුවට යොමු අගය රඳවා ඇති යොමු විචල්‍යයට බැඳී ඇති නමකි (අභ්‍යන්තරව නූලක් ලෙස ග්‍රහණය කර ඇත). අභ්‍යන්තර ශබ්ද කෝෂයේ යතුර වන්නේ විචල්‍යයේ නමයි, එම ශබ්ද කෝෂ අයිතමයේ අගය කොටස ඉලක්කයට යොමු අගය ගබඩා කරයි.

යොමු අගයන් පයිතන් තුළ සඟවා ඇත. විමර්ශන අගය ගබඩා කිරීම සඳහා පැහැදිලි පරිශීලක වර්ගයක් නොමැත. කෙසේ වෙතත්, ඔබට විමර්ශන විචල්‍යය ලෙස ලැයිස්තු මූලද්‍රව්‍යයක් (හෝ වෙනත් සුදුසු බහාලුම් වර්ගයක මූලද්‍රව්‍යයක්) භාවිතා කළ හැකිය, මන්ද සියලු බහාලුම් මූලද්‍රව්‍ය ඉලක්කගත වස්තු වෙත යොමු කිරීමක් ලෙස ගබඩා කරයි. වෙනත් වචන වලින් කිවහොත්, මූලද්රව්ය ඇත්ත වශයෙන්ම බහාලුම් තුළ අඩංගු නොවේ - මූලද්රව්ය සඳහා යොමු කිරීම් පමණි.


1
සැබවින්ම මෙය යොමු අගය අනුව එහි සමත් බව සනාථ කරයි. මෙම පිළිතුර සඳහා +1 උදාහරණය හොඳ නැත.
BugShotGG

31
නව පාරිභාෂිතය සොයා ගැනීම ("යොමු අගය හරහා ගමන් කිරීම" හෝ "වස්තුවෙන් ඇමතුම" වැනි ප්‍රයෝජනවත් නොවේ) "අමතන්න (අගය | යොමු | නම)" යනු සම්මත පද වේ. “යොමුව” යනු සම්මත යෙදුමකි. සම්මත පාරිභාෂිතය භාවිතා කරමින් පයිතන්, ජාවා සහ වෙනත් භාෂා ගණනාවක හැසිරීම නිවැරදිව විස්තර කරයි.
cayhorstmann

4
ayCayhorstmann: ගැටළුව වන්නේ පයිතන් විචල්‍යයට වෙනත් භාෂාවලට සමාන අර්ථයක් නොමැති වීමයි. මේ ආකාරයෙන්, ඇමතුමකින් ඇමතුම මෙතැනට නොගැලපේ. එසේම, ඔබ යොමුව යන පදය හරියටම අර්ථ දක්වන්නේ කෙසේද? අවිධිමත් ලෙස, පයිතන් මාර්ගය පහසුවෙන් විස්තර කළ හැක්කේ වස්තුවේ ලිපිනය පසු කිරීමෙනි. නමුත් එය බෙදා හැරිය හැකි පයිතන් ක්‍රියාත්මක කිරීම සමඟ නොගැලපේ.
pepr

1
මම මෙම පිළිතුරට කැමතියි, නමුත් උදාහරණය සැබවින්ම ප්‍රවාහයට උදව් කරන්නේද නැතහොත් රිදවන්නේද යන්න ඔබ සලකා බැලිය හැකිය. එසේම, ඔබ 'යොමු අගය' වෙනුවට 'වස්තු යොමු කිරීම' වෙනුවට ආදේශ කරනු ලැබුවහොත්, මෙහි දැක්වෙන පරිදි, අපට 'නිල' ලෙස සැලකිය හැකි පාරිභාෂිතය භාවිතා කරනු ඇත: කාර්යයන් නිර්වචනය කිරීම
අවංක අබේ

2
එම උපුටා දැක්වීමේ අවසානයේ දැක්වෙන පාදසටහනක් ඇත, එහි මෙසේ සඳහන් වේ: “ඇත්ත වශයෙන්ම, වස්තු යොමු කිරීම මගින් ඇමතීම වඩා හොඳ විස්තරයක් වනු ඇත, මන්ද විකෘති වස්තුවක් සම්මත වුවහොත්, ඇමතුම්කරු විසින් ඇමතුමෙහි යම් වෙනස්කමක් දකිනු ඇත ... “ ව්‍යාකූලත්වයට හේතු වී ඇත්තේ වෙනත් භාෂාවන් සමඟ ස්ථාපිත පාරිභාෂිතය ගැලපීමට උත්සාහ කිරීම බව මම ඔබ සමඟ එකඟ වෙමි. අර්ථ නිරූපණය පසෙකට දැමුවහොත් තේරුම් ගත යුතු කරුණු නම්: ශබ්ද කෝෂ / නාම අවකාශයන්, නාම බන්ධන මෙහෙයුම් සහ නම → දර්ශක → වස්තුව (ඔබ දැනටමත් දන්නා පරිදි) සම්බන්ධතාවය.
අවංක අබේ

58

පයිතන් හි විචල්යයන් නොමැත

පරාමිති සම්මත කිරීම අවබෝධ කර ගැනීමේ යතුර නම් “විචල්‍යයන්” ගැන සිතීම නතර කිරීමයි. පයිතන් හි නම් සහ වස්තූන් ඇති අතර ඒවා විචල්යයන් මෙන් පෙනේ, නමුත් සෑම විටම තුන වෙන්කර හඳුනා ගැනීම ප්රයෝජනවත් වේ.

  1. පයිතන්ට නම් සහ වස්තු ඇත.
  2. පැවරුම වස්තුවකට නමක් බැඳ තබයි.
  3. ශ්‍රිතයක් තුළට තර්කයක් යැවීම මඟින් නමක් (ශ්‍රිතයේ පරාමිති නාමය) වස්තුවකට බැඳේ.

එහි ඇත්තේ එපමණයි. විකෘතිතාව මෙම ප්‍රශ්නයට අදාල නොවේ.

උදාහරණයක්:

a = 1

මෙය නම a1 අගය දරණ පූර්ණ සංඛ්‍යා වර්ගයකට සම්බන්ධ කරයි .

b = x

මෙය bනම xදැනට බැඳී ඇති එකම වස්තුවට නම බැඳ තබයි . පසුව, bනමට xතවදුරටත් නමට කිසිදු සම්බන්ධයක් නැත.

පයිතන් 3 භාෂා යොමුවෙහි 3.1 සහ 4.2 කොටස් බලන්න .

ප්රශ්නයේ උදාහරණය කියවන්නේ කෙසේද

ප්‍රශ්නයේ පෙන්වා ඇති කේතයේ, ප්‍රකාශය අගය දරණ වස්තුවට (ශ්‍රිතයේ විෂය පථයට ) self.Change(self.variable)බන්ධනය වන අතර පැවරුම (ක්‍රියාකාරීත්වයේ ) නැවත එම නමම පවරයි: වෙනත් වස්තුවකට (එය සිදු වේ නූලක් රඳවා තබා ගැනීමට නමුත් එය සම්පූර්ණයෙන්ම වෙනත් දෙයක් විය හැකිය).varChange'Original'var = 'Changed'Change

යොමු කිරීමෙන් සමත් වන්නේ කෙසේද

එබැවින් ඔබට වෙනස් කිරීමට අවශ්‍ය දෙය විකෘති වස්තුවක් නම්, කිසිදු ගැටළුවක් නොමැත, මන්දයත් සියල්ල effectively ලදායි ලෙස යොමු කිරීමෙනි.

එය වෙනස් කළ නොහැකි වස්තුවක් නම් (උදා: බූල්, අංක, නූල්), යා යුතු මාර්ගය එය විකෘති වස්තුවක ඔතා තැබීමයි.
මේ සඳහා ඉක්මන් හා අපිරිසිදු විසඳුම එක් මූලද්‍රව්‍ය ලැයිස්තුවකි (ඒ වෙනුවට self.variable, සමත් [self.variable]සහ ශ්‍රිතය වෙනස් කිරීම var[0]).
වඩාත් පයිතොනික් ප්‍රවේශය වනුයේ සුළු, එක්-ගුණාංග පන්තියක් හඳුන්වා දීමයි. ශ්‍රිතයට පන්තියේ උදාහරණයක් ලැබෙන අතර ගුණාංගය හසුරුවයි.


21
"පයිතන්ට විචල්‍යයන් නොමැත" යනු මෝඩ හා ව්‍යාකූල සටන්
නෙඩ් බැට්චෙල්ඩර්

10
එය කම්පනයට පත් විය හැකි නමුත් එය මෝඩ නැත. එය ව්‍යාකූල යැයි මම නොසිතමි: එය එළඹෙන පැහැදිලි කිරීම සඳහා ලබන්නාගේ මනස විවෘත කර ඇයව ප්‍රයෝජනවත් "විචල්‍යයන් වෙනුවට ඔවුන් සතුව ඇත්තේ කුමක් දැයි මම සිතමි" යන ආකල්පය තුළට යොමු කරයි. (ඔව්, ඔබේ
සැතපුම් ගණන

13
ජාවාස්ක්‍රිප්ට් හි විචල්‍යයන් නොමැති බව ඔබ පවසනවාද? ඒවා පයිතන් මෙන් ක්‍රියා කරයි. එසේම, ජාවා, රූබි, පීඑච්පී, .... වඩා හොඳ ඉගැන්වීමේ ක්‍රමයක් නම්, "පයිතන්ගේ විචල්‍යයන් සී වලට වඩා වෙනස් ලෙස ක්‍රියා කරයි."
නෙඩ් බැට්චෙල්ඩර්

9
ඔව්, ජාවාට විචල්යයන් ඇත. පයිතන්, සහ ජාවාස්ක්‍රිප්ට්, රූබි, පීඑච්පී යනාදිය ද එසේ වේ. intවිචල්‍යයක් ප්‍රකාශ කරන ජාවාහි ඔබ නොකියනු ඇත Integer. ඔවුන් දෙදෙනාම විචල්යයන් ප්රකාශ කරති. මෙම Integerවිචල්ය වස්තුවක් වන අතර, එම intවිචල්ය ප්රාථමික වේ. උදාහරණයක් ලෙස, ඔබේ විචල්‍යයන් ක්‍රියා කරන ආකාරය පෙන්වීමෙන් ඔබ නිරූපණය a = 1; b = a; a++ # doesn't modify bකළේය. පයිතන් වලද එය සත්‍යයකි ( පයිතන් හි += 1නොමැති බැවින් භාවිතා කිරීම ++)!
නෙඩ් බැට්චෙල්ඩර්

2
"විචල්යය" යන සංකල්පය සංකීර්ණ හා බොහෝ විට නොපැහැදිලි ය: විචල්යය යනු නමක් මගින් හඳුනාගත් අගයක් සඳහා වන බහාලුමකි. පයිතන්හි, අගයන් වස්තු වේ, බහාලුම් වස්තු වේ (ගැටලුව බලන්න?) සහ නම් ඇත්ත වශයෙන්ම වෙනම දේවල් වේ. මේ ආකාරයෙන් විචල්යයන් පිළිබඳ නිවැරදි අවබෝධයක් ලබා ගැනීම වඩා දැඩි බව මම විශ්වාස කරමි . නම් සහ වස්තු පැහැදිලි කිරීම වඩා දුෂ්කර බව පෙනේ, නමුත් ඇත්ත වශයෙන්ම එය සරල ය.
ලුට්ස් ප්‍රීචෙල්ට්

44

මම සාමාන්‍යයෙන් භාවිතා කරන සරල උපක්‍රමයක් නම් එය ලැයිස්තුවකට එතීමයි:

def Change(self, var):
    var[0] = 'Changed'

variable = ['Original']
self.Change(variable)      
print variable[0]

(ඔව්, මෙය අපහසුතාවයක් විය හැකි බව මම දනිමි, නමුත් සමහර විට මෙය කිරීමට තරම් සරල ය.)


7
පයිතන් පසු විපරම් නොකිරීමේ ගැටලුවට අත්‍යවශ්‍ය විසඳුමක් ලබා දෙන කුඩා පෙළ සඳහා +1. . මෙය, සහ ශ්‍රිතය තුළ ඇති තර්කයට ලැයිස්තුවේ 0 වන අංගය ලෙස සලකන්න.)
එම් කැට්ස්

5
හොඳයි. Ref හරහා ගමන් කිරීමට, [] ගේ ඔතා.
ජස්ටස්

39

(සංස්කරණය කරන්න - බ්ලෙයාර් සිය අතිවිශාල ජනප්‍රිය පිළිතුර යාවත්කාලීන කර ඇති අතර එය දැන් නිවැරදි ය)

වර්තමාන තනතුරට වැඩි ඡන්ද ප්‍රමාණයක් (බ්ලෙයාර් කොන්රාඩ් විසින්) ලබා දී ඇති අතර, එහි ප්‍රති result ල සම්බන්ධයෙන් නිවැරදිව සිටීම නොමඟ යවන සුළු වන අතර එහි අර්ථ දැක්වීම් මත පදනම්ව දේශසීමා වැරදිය. පරිශීලකයාට යොමු කිරීම හෝ අගය අනුව ගමන් කිරීම සඳහා ඉඩ සලසන බොහෝ භාෂා (සී වැනි) ඇතත්, පයිතන් ඒවායින් එකක් නොවේ.

ඩේවිඩ් කෝර්නපියෝගේ පිළිතුර සැබෑ පිළිතුර වෙත යොමු වන අතර නිර්වචන නොමැති අතර බ්ලෙයාර් කොන්රාඩ්ගේ තනතුරේ හැසිරීම නිවැරදි යැයි පෙනෙන්නේ මන්දැයි පැහැදිලි කරයි.

පයිතන් අගය අනුව ගමන් කරන තාක් දුරට, සියලු භාෂා අගය අනුව ගමන් කරනුයේ යම් දත්ත කොටසක් (එය “වටිනාකමක්” හෝ “යොමු කිරීමක්” වේවා) යැවිය යුතු බැවිනි. කෙසේ වෙතත්, සී ක්‍රමලේඛකයෙකු ඒ ගැන සිතනු ඇතැයි යන අර්ථයෙන් පයිතන් අගය පසුකර යන බවක් එයින් අදහස් නොවේ.

ඔබට හැසිරීම අවශ්‍ය නම්, බ්ලෙයාර් කොන්රාඩ්ගේ පිළිතුර හොඳයි. නමුත් ඔබට පයිතන් අගය ඉක්මවා නොයන්නේ මන්දැයි යන්න පිළිබඳ දැනුමක් හා බෝල්ට් දැන ගැනීමට අවශ්‍ය නම්, ඩේවිඩ් කෝර්නපියෝගේ පිළිතුර කියවන්න.


4
සෑම භාෂාවක්ම අගය අනුව කැඳවන බව සරලවම සත්‍ය නොවේ. සී ++ හෝ පැස්කල් හි (සහ නිසැකවම මා නොදන්නා බොහෝ අය), ඔබට ඇමතුමක් යොමු කර ඇත. උදාහරණයක් ලෙස, C ++ හි, එයට void swap(int& x, int& y) { int temp = x; x = y; y = temp; }ලබා දුන් විචල්‍යයන් මාරු කරයි. පැස්කල්හිදී, ඔබ varඒ වෙනුවට භාවිතා කරයි &.
cayhorstmann

2
මම හිතුවේ මම මීට බොහෝ කලකට පෙර පිළිතුරු දුන් නමුත් මට එය නොපෙනේ. සම්පූර්ණත්වය සඳහා - කේහෝර්ස්ට්මන් මගේ පිළිතුර වැරදියට වටහාගෙන ඇත. සී / සී ++ සම්බන්ධයෙන් බොහෝ දෙනා මුලින් ඉගෙන ගන්නා වචන අනුව සෑම දෙයක්ම අගය අනුව කැඳවීමක් යැයි මම නොකියමි . හුදෙක් යම් අගයක් සම්මත කිරීම (අගය, නම, දර්ශකය යනාදිය) සහ බ්ලෙයාර්ගේ මුල් පිළිතුරේ භාවිතා කර ඇති වචන සාවද්‍ය ය.
කෝබේ ජෝන්

25

ඔබට මෙහි හොඳ පිළිතුරු කිහිපයක් තිබේ.

x = [ 2, 4, 4, 5, 5 ]
print x  # 2, 4, 4, 5, 5

def go( li ) :
  li = [ 5, 6, 7, 8 ]  # re-assigning what li POINTS TO, does not
  # change the value of the ORIGINAL variable x

go( x ) 
print x  # 2, 4, 4, 5, 5  [ STILL! ]


raw_input( 'press any key to continue' )

2
ඔව්, කෙසේ වෙතත් ඔබ x = [2, 4, 4, 5, 5], y = x, X [0] = 1, x # [1, 4, 4, 5, 5] මුද්‍රණය කරන්න y # [1 , 4, 4, 5, 5]
laycat

19

මෙම අවස්ථාවෙහිදී, varක්‍රමයේ නම් කර ඇති විචල්‍යයට Changeයොමු කිරීමක් ලබා self.variableදී ඇති අතර, ඔබ වහාම එයට නූලක් පවරයි var. එය තවදුරටත් පෙන්වා නැත self.variable. ඔබ දත්ත ව්යුහය වෙනස් නම් සිදු වන්නේ කුමක්ද කියා පහත දැක්වෙන කේතය ඇබිත්ත සංදර්ශන විසින් පෙන්වා varහා self.variable, මේ අවස්ථාවේ දී ලැයිස්තුවක්:

>>> class PassByReference:
...     def __init__(self):
...         self.variable = ['Original']
...         self.change(self.variable)
...         print self.variable
...         
...     def change(self, var):
...         var.append('Changed')
... 
>>> q = PassByReference()
['Original', 'Changed']
>>> 

මට විශ්වාසයි වෙනත් කෙනෙකුට මෙය තවදුරටත් පැහැදිලි කළ හැකිය.


19

පයිතන්ගේ පාස්-බයි-පැවරුම් යෝජනා ක්‍රමය සී ++ හි යොමු පරාමිති විකල්පයට සමාන නොවේ, නමුත් එය ප්‍රායෝගිකව සී භාෂාවේ (සහ වෙනත්) තර්ක-සම්මත ආකෘතියට බෙහෙවින් සමාන ය:

  • වෙනස් කළ නොහැකි තර්ක effectively ලදායී ලෙස “ වටිනාකමින් ” සම්මත වේ. පූර්ණ සංඛ්‍යා හා නූල් වැනි වස්තූන් පිටපත් කිරීම වෙනුවට වස්තු යොමු කිරීම මඟින් සම්මත කරනු ලැබේ, නමුත් ඔබට කෙසේ හෝ වෙනස් කළ නොහැකි වස්තූන් තැනින් තැන වෙනස් කළ නොහැකි නිසා, එහි ප්‍රති a ලය පිටපතක් සෑදීමට සමාන ය.
  • විකෘති තර්ක effectively ලදායි ලෙස “ දර්ශකය මගින් ” සම්මත කරනු ලැබේ . ලැයිස්තු සහ ශබ්ද කෝෂ වැනි වස්තූන් ද වස්තු යොමු කිරීම මඟින් සම්මත කරනු ලැබේ, එය සී අරා දර්ශකයන් ලෙස ගමන් කරන ආකාරයට සමාන වේ - විකෘති වස්තූන් ශ්‍රිතයේ දී වෙනස් කළ හැකිය, සී අරා මෙන්.

17

ඔබට විකෘති වස්තුවක් තිබිය යුතු බව ඔබට පැවසිය හැකි නමුත්, ගෝලීය විචල්‍යයන් ඔබට උදව් කිරීමට හෝ මේ ආකාරයේ ගැටලුවක් විසඳීමට හැකි බැවින් ඒවා පරීක්ෂා කර බැලීමට මම ඔබට යෝජනා කරමි!

http://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python

උදාහරණයක්:

>>> def x(y):
...     global z
...     z = y
...

>>> x
<function x at 0x00000000020E1730>
>>> y
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined
>>> z
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'z' is not defined

>>> x(2)
>>> x
<function x at 0x00000000020E1730>
>>> y
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined
>>> z
2

5
ඒ හා සමාන ප්‍රතිචාරයක් පළ කිරීමට මා පෙලඹුණි- කාර්යයන් අතර බෙදාගෙන ඇති ගෝලීය විචල්‍යයක් භාවිතා කිරීම තමාට අවශ්‍ය දේ බව මුල් ප්‍රශ්නකරුවා නොදැන සිටින්නට ඇත. මෙන්න මම බෙදාගෙන ඇති සබැඳිය: stackoverflow.com/questions/423379/… imTim ට පිළිතුරු වශයෙන්, ස්ටැක් පිටාර ගැලීම යනු ප්‍රශ්නෝත්තර වෙබ් අඩවියක් පමණක් නොව, එය ශක්තිමත් හා වඩා සූක්ෂ්ම ලෙස ලබා ගන්නා විශාල විමර්ශන දැනුමේ ගබඩාවකි. සක්‍රිය විකියක් වැනි- වැඩි ආදානයක් සහිත.
මැක්ස් පී මාගී

14

මෙහි පිළිතුරු පිළිබඳ තීක්ෂ්ණ බුද්ධියක් ඇති නමුත් අතිරේක කරුණක් මෙහි පැහැදිලිව සඳහන් කර නැති බව මම සිතමි. පයිතන් ප්‍රලේඛනයෙන් උපුටා දැක්වීම https://docs.python.org/2/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python

"පයිතන්හි, ශ්‍රිතයක් තුළ පමණක් සඳහන් වන විචල්‍යයන් ව්‍යංගයෙන් ගෝලීය වේ. විචල්‍යයක් ශ්‍රිතයේ ශරීරය තුළ ඕනෑම තැනක නව අගයක් ලබා දෙන්නේ නම්, එය දේශීය යැයි උපකල්පනය කෙරේ. විචල්‍යයක් කවදා හෝ ශ්‍රිතය තුළ නව අගයක් ලබා දෙන්නේ නම්, විචල්‍යය ව්‍යංගයෙන් දේශීය වන අතර, ඔබ එය 'ගෝලීය' ලෙස පැහැදිලිව ප්‍රකාශ කළ යුතුය. මුලදී මඳක් පුදුමයට පත් වුවද, මොහොතකට සලකා බැලීමෙන් මෙය පැහැදිලි වේ.එම පැත්තෙන්, පවරා ඇති විචල්‍යයන් සඳහා ගෝලීය අවශ්‍යතාවය අනපේක්ෂිත අතුරු ආබාධවලට එරෙහිව බාධාවක් සපයයි. අනෙක් අතට, සියලු ගෝලීය යොමු කිරීම් සඳහා ගෝලීය අවශ්‍ය නම්, ඔබ සැමවිටම ගෝලීයව භාවිතා කරනු ඇත.ඔබට ගොඩනංවන ලද ශ්‍රිතයක් හෝ ආනයනික මොඩියුලයක අංගයක් පිළිබඳ සෑම සඳහනක්ම ගෝලීය ලෙස ප්‍රකාශ කළ යුතුය. අතුරු ආබාධ හඳුනා ගැනීම සඳහා වන ගෝලීය ප්‍රකාශනයේ ප්‍රයෝජනය පරාජය කරනු ඇත.

විකෘති වස්තුවක් ශ්‍රිතයකට යොමු කිරීමේදී පවා මෙය තවමත් අදාළ වේ. තවද, වස්තුවට පැවරීම සහ ශ්‍රිතයේ වස්තුව ක්‍රියාත්මක කිරීම අතර හැසිරීමේ වෙනසට හේතුව මට පැහැදිලිව පැහැදිලි කරයි.

def test(l):
    print "Received", l , id(l)
    l = [0, 0, 0]
    print "Changed to", l, id(l)  # New local object created, breaking link to global l

l= [1,2,3]
print "Original", l, id(l)
test(l)
print "After", l, id(l)

ලබා දෙයි:

Original [1, 2, 3] 4454645632
Received [1, 2, 3] 4454645632
Changed to [0, 0, 0] 4474591928
After [1, 2, 3] 4454645632

ගෝලීය ලෙස ප්‍රකාශයට පත් නොකරන ලද ගෝලීය විචල්‍යයකට පැවරීම නව දේශීය වස්තුවක් නිර්මාණය කර මුල් වස්තුවට ඇති සම්බන්ධය බිඳ දමයි.


10

pass by objectපයිතන් හි භාවිතා වන සංකල්පයේ සරල (මම බලාපොරොත්තු වෙමි) පැහැදිලි කිරීම මෙන්න .
ඔබ කිසියම් වස්තුවක් ශ්‍රිතයට යැවූ විට, එම වස්තුවම සම්මත වේ (පයිතන්හි ඇති වස්තුව ඇත්ත වශයෙන්ම ඔබ වෙනත් ක්‍රමලේඛන භාෂාවලින් වටිනාකමක් ලෙස හඳුන්වනු ඇත) මෙම වස්තුවට යොමු නොවේ. වෙනත් වචන වලින් කිවහොත්, ඔබ අමතන විට:

def change_me(list):
   list = [1, 2, 3]

my_list = [0, 1]
change_me(my_list)

සත්‍ය වස්තුව - [0, 1] (එය වෙනත් ක්‍රමලේඛන භාෂාවල අගයක් ලෙස හැඳින්වේ) සම්මත වෙමින් පවතී. එබැවින් ඇත්ත වශයෙන්ම ශ්‍රිතය change_meමෙවැනි දෙයක් කිරීමට උත්සාහ කරනු ඇත:

[0, 1] = [1, 2, 3]

එය පැහැදිලිවම ශ්‍රිතයට ලබා දුන් වස්තුව වෙනස් නොකරනු ඇත. ශ්‍රිතය මේ වගේ නම්:

def change_me(list):
   list.append(2)

එවිට ඇමතුම ප්‍රති result ල වනු ඇත:

[0, 1].append(2)

එය පැහැදිලිවම වස්තුව වෙනස් කරනු ඇත. මෙම පිළිතුර එය හොඳින් පැහැදිලි කරයි.


2
ගැටළුව වන්නේ පැවරුම ඔබ බලාපොරොත්තු වනවාට වඩා වෙනත් දෙයක් කිරීමයි. මෙම list = [1, 2, 3]හේතු නැවත භාවිතවන listවෙන දෙයක් සඳහා නම හා මුලින් සම්මත වස්තුව forgeting. කෙසේ වෙතත්, ඔබට උත්සාහ කළ හැකිය list[:] = [1, 2, 3](මාර්ගය listවන විට විචල්‍යයක වැරදි නමකි. ඒ ගැන සිතීම [0, 1] = [1, 2, 3]සම්පූර්ණ විකාරයකි. කෙසේ වෙතත්, ඔබ සිතන්නේ කුමක්ද යන්නෙන් අදහස් කරන්නේ
වස්තුවම

@pepr වස්තු වචනාර්ථමය නොවේ. ඒවා වස්තු ය. ඔවුන් ගැන කතා කිරීමට ඇති එකම ක්‍රමය නම් කිහිපයක් ලබා දීමයි. ඔබ එය ග්‍රහණය කරගත් පසු එය එතරම් සරල නමුත් එය පැහැදිලි කිරීමට අතිශයින්ම සංකීර්ණ වන්නේ එබැවිනි. :-)
වේකි

Ee වේකි: මම ඒ ගැන දන්නවා. කෙසේ වෙතත්, ලැයිස්තු වචනාර්ථය ලැයිස්තු වස්තුව බවට පරිවර්තනය වේ. ඇත්ත වශයෙන්ම, පයිතන් හි ඇති ඕනෑම වස්තුවක් නමක් නොමැතිව පැවතිය හැකි අතර, කිසිදු නමක් ලබා නොදුන් විට පවා එය භාවිතා කළ හැකිය. නිර්නාමික වස්තූන් ගැන ඔබට ඒවා ගැන සිතිය හැකිය. වස්තූන් ලැයිස්තුවක මූලද්‍රව්‍යයන් ගැන සිතන්න. ඔවුන්ට නමක් අවශ්‍ය නැත. ලැයිස්තුව හරහා සුචිගත කිරීම හෝ නැවත කිරීම මඟින් ඔබට ඒවාට ප්‍රවේශ විය හැකිය. කෙසේ වෙතත්, මම තරයේ කියා සිටින්නේ [0, 1] = [1, 2, 3]නරක උදාහරණයක් බවයි. පයිතන් වල එවැනි දෙයක් නැත.
pepr

@pepr: මම අනිවාර්යයෙන්ම පයිතන් අර්ථ දැක්වීමේ නම්, සාමාන්‍ය නම් පමණක් අදහස් නොකරමි. ඇත්ත වශයෙන්ම alist[2]ඇලිස්ට්හි තුන්වන මූලද්රව්යයේ නමක් ලෙස ගණන් ගැනේ. නමුත් මම හිතන්නේ ඔබේ ගැටලුව කුමක්දැයි මම වරදවා වටහා ගත්තා. :-)
වේකි

ආග්. මගේ ඉංග්‍රීසි පැහැදිලිවම මගේ පයිතන්ට වඩා නරක ය. :-) මම නැවත වරක් උත්සාහ කරමි. මම කිව්වේ ඔබ වස්තුවට නම් කිහිපයක් දිය යුතු බවයි. එම “නම්” මගින් මා අදහස් කළේ “පයිතන් විසින් අර්ථ දක්වා ඇති නම්” යන්නයි. මම දන්නවා පයිතන් යාන්ත්‍රණයන්, කරදර වෙන්න එපා.
වේකි

8

පයිතන් හි මෙම දේවල් ක්‍රියාත්මක වන්නේ කෙසේද යන්න පිළිබඳ සියලු විශිෂ්ට පැහැදිලි කිරීම් හැරුණු විට, ගැටලුව සඳහා සරල යෝජනාවක් මා දකින්නේ නැත. ඔබ වස්තූන් හා සිද්ධීන් නිර්මාණය කරන බවක් පෙනෙන්නට ඇති පරිදි, නිදර්ශන විචල්‍යයන් හැසිරවීමේ හා ඒවා වෙනස් කිරීමේ පයිතොනික් ක්‍රමය පහත දැක්වේ:

class PassByReference:
    def __init__(self):
        self.variable = 'Original'
        self.Change()
        print self.variable

    def Change(self):
        self.variable = 'Changed'

නිදර්ශන ක්‍රම වලදී, ඔබ සාමාන්‍යයෙන් යොමු වන්නේ selfනිදසුන් ගුණාංග වෙතය. නිදර්ශන ගුණාංග සැකසීම __init__සහ ඒවා කියවීමේ හෝ වෙනස් කිරීමේ අවස්ථා වලදී සාමාන්‍ය දෙයකි . ඔබ selfපළමු තර්කය වෙත යොමු වන්නේ එබැවිනි def Change.

තවත් විසඳුමක් වනුයේ මේ වගේ ස්ථිතික ක්‍රමයක් නිර්මාණය කිරීමයි:

class PassByReference:
    def __init__(self):
        self.variable = 'Original'
        self.variable = PassByReference.Change(self.variable)
        print self.variable

    @staticmethod
    def Change(var):
        var = 'Changed'
        return var

6

භාෂාවට එය කළ නොහැකි වුවද, වස්තුවක් යොමු කිරීම සඳහා කුඩා උපක්‍රමයක් ඇත. එය ජාවා වලද ක්‍රියාත්මක වේ, එය එක් අයිතමයක් සහිත ලැයිස්තුවයි. ;-)

class PassByReference:
    def __init__(self, name):
        self.name = name

def changeRef(ref):
    ref[0] = PassByReference('Michael')

obj = PassByReference('Peter')
print obj.name

p = [obj] # A pointer to obj! ;-)
changeRef(p)

print p[0].name # p->name

එය අවලස්සන කඩුල්ලක්, නමුත් එය ක්රියා කරයි. ;- පී


pයනු විකෘති ලැයිස්තුගත වස්තුවක් වෙත යොමු වීමකි obj. 'P' යන සඳහන සම්මත වේ changeRef. ඇතුළත changeRef, නව යොමු කිරීමක් සාදනු ලැබේ (නව යොමුව හැඳින්වේ ref) එය යොමු කරන එකම ලැයිස්තු වස්තුවට pයොමු කරයි. නමුත් ලැයිස්තු විකෘති වන බැවින්, ලැයිස්තුවේ වෙනස්කම් යොමු දෙකෙන්ම දැකිය හැකිය . මෙම අවස්ථාවේදී, ඔබ refදර්ශකය 0 දර්ශකයේ වෙනස් කිරීම සඳහා යොමුව භාවිතා කළ අතර එමඟින් එය පසුව PassByReference('Michael')වස්තුව ගබඩා කරයි . ලැයිස්තු වස්තුව වෙනස් කිරීම භාවිතා කර ඇති refනමුත් මෙම වෙනස දෘශ්‍යමාන වේ p.
මිං ට්‍රාන්

දැන්, යොමු කිරීම් pසහ refතනි වස්තුව ගබඩා කරන ලැයිස්තු වස්තුවකට යොමු කරන්න , PassByReference('Michael'). එබැවින් එය p[0].nameනැවත පැමිණේ Michael. ඇත්ත වශයෙන්ම, refදැන් විෂය පථයෙන් බැහැර වී ඇති අතර කසළ එකතු කළ හැකි නමුත් සියල්ලම එක හා සමානයි.
මිං ට්‍රාන්

යොමුව හා සම්බන්ධ මුල් වස්තුවෙහි පුද්ගලික නිදර්ශන විචල්‍යය ඔබ වෙනස් කර නැත . ඇත්ත වශයෙන්ම, නැවත පැමිණෙනු ඇත. ඉහත සඳහන් අදහස් දැක්වීම් ලබා දී ඇති අර්ථ දැක්වීම උපකල්පනය කරයි . namePassByReferenceobjobj.namePeterMark Ransom
මිං ට්‍රාන්

කාරණය නම්, එය අනවසරයෙන් සිදුවන බව මම එකඟ නොවෙමි (එය ක්‍රියා කරන දෙයක් ගැන සඳහන් කිරීමට අදහස් කරන නමුත් නොදන්නා, පරීක්ෂා නොකළ හෝ ක්‍රියාත්මක කරන්නා විසින් බලාපොරොත්තු නොවූ හේතු නිසා). ඔබ හුදෙක් එක් PassByReferenceවස්තුවක් PassByReferenceඔබේ ලැයිස්තුවේ වෙනත් වස්තුවක් සමඟ ප්‍රතිස්ථාපනය කර වස්තු දෙකේ දෙවැන්න වෙත යොමු කරයි.
මිං ට්‍රාන්

5

ෆෝට්රාන් කේත කිහිපයක් ඉක්මනින් පයිතන් බවට පරිවර්තනය කිරීම සඳහා මම පහත ක්‍රමය භාවිතා කළෙමි. ඇත්ත, එය මුල් ප්‍රශ්නය මතු වූ බැවින් එය යොමු කිරීමකින් සම්මත නොවන නමුත් සමහර අවස්ථාවල එය සරල කෘතියකි.

a=0
b=0
c=0
def myfunc(a,b,c):
    a=1
    b=2
    c=3
    return a,b,c

a,b,c = myfunc(a,b,c)
print a,b,c

ඔව්, මෙය මගේ භාවිතයේ දී ද 'යොමු කිරීම හරහා යොමු කිරීම' විසඳයි. මට ශ්‍රිතයක් ඇත, එය මූලික වශයෙන් a හි අගයන් පිරිසිදු කර dictනැවත ලබා දෙයි dict. කෙසේ වෙතත්, පිරිසිදු කිරීමේදී පද්ධතියේ කොටසක් නැවත ගොඩනැඟීම අවශ්‍ය බව පෙනෙන්නට තිබේ. එමනිසා, ශ්‍රිතය පිරිසිදු කළ දේ නැවත ලබා දෙනවා පමණක් නොව නැවත dictගොඩනැඟීම සං signal ා කළ හැකිය. මම boolයොමු කිරීමක් සම්මත කිරීමට උත්සාහ කළෙමි , නමුත් ofc එය ක්‍රියාත්මක නොවේ. මෙය විසඳන්නේ කෙසේදැයි හදුනාගැනීමේදී, ඔබේ විසඳුම (මූලික වශයෙන් ටුපල් එකක් ආපසු ලබා දීම) වඩාත් හොඳින් වැඩ කිරීමට මට හැකි විය.
kasimir

3

යොමු කිරීම පාස් යනු පයිතන්ට හොඳින් ගැලපෙන කිසිවක් නොවන අතර කලාතුරකින් භාවිතා කළ යුතු අතර ඇත්ත වශයෙන්ම දැනට පවතින වස්තුව දේශීය විචල්‍යයකට පවරා ගැනීමට හෝ හැඳින්වෙන ශ්‍රිතයක ඇතුළත සිට දේශීය විචල්‍යයක් නැවත පැවරීමට ක්‍රියා කළ හැකි සමහර ක්‍රියාමාර්ග තිබේ.

මූලික අදහස නම්, එම ප්‍රවේශය කළ හැකි ශ්‍රිතයක් තිබීම සහ වෙනත් කාර්යයන් වෙත වස්තුවක් ලෙස යැවීම හෝ පන්තියක ගබඩා කිරීම ය.

එක් ක්‍රමයක් නම් global(ගෝලීය විචල්‍යයන් සඳහා) හෝ nonlocal(ශ්‍රිතයක දේශීය විචල්‍යයන් සඳහා) එතීමේ ශ්‍රිතයක් භාවිතා කිරීමයි.

def change(wrapper):
    wrapper(7)

x = 5
def setter(val):
    global x
    x = val
print(x)

එකම අදහස delවිචල්‍යයක් කියවීම හා අනුභව කිරීම සඳහා ක්‍රියා කරයි .

හුදෙක් කියවීම සඳහා භාවිතා lambda: xකළ හැකි කෙටි ක්‍රමයක් පවා ඇත, එය ඇමතිය හැකි ආපසු ලබා දෙන විට x හි වත්මන් අගය නැවත ලබා දෙයි. මෙය තරමක් past ත අතීතයේ භාෂාවල භාවිතා වන "නමෙන් අමතන්න" වැනි ය.

විචල්‍යයකට ප්‍රවේශ වීම සඳහා ආවරණ 3 ක් පසු කිරීම තරමක් නොසැලකිලිමත් වන බැවින් ඒවා ප්‍රොක්සි ලක්ෂණයක් ඇති පන්තියකට ඔතා තැබිය හැකිය:

class ByRef:
    def __init__(self, r, w, d):
        self._read = r
        self._write = w
        self._delete = d
    def set(self, val):
        self._write(val)
    def get(self):
        return self._read()
    def remove(self):
        self._delete()
    wrapped = property(get, set, remove)

# left as an exercise for the reader: define set, get, remove as local functions using global / nonlocal
r = ByRef(get, set, remove)
r.wrapped = 15

පයිතන් “පරාවර්තන” ආධාරයෙන් එම විෂය පථය තුළ නිශ්චිතවම කාර්යයන් නිර්වචනය නොකර දී ඇති විෂය පථයක් තුළ නමක් / විචල්‍යයක් නැවත පැවරිය හැකි වස්තුවක් ලබා ගත හැකිය:

class ByRef:
    def __init__(self, locs, name):
        self._locs = locs
        self._name = name
    def set(self, val):
        self._locs[self._name] = val
    def get(self):
        return self._locs[self._name]
    def remove(self):
        del self._locs[self._name]
    wrapped = property(get, set, remove)

def change(x):
    x.wrapped = 7

def test_me():
    x = 6
    print(x)
    change(ByRef(locals(), "x"))
    print(x)

මෙහිදී ByRefපන්තිය ශබ්ද කෝෂ ප්‍රවේශයක් ආවරණය කරයි. එබැවින් ආරෝපිත ප්‍රවේශය wrappedසම්මත ශබ්දකෝෂයේ අයිතම ප්‍රවේශයකට පරිවර්තනය වේ. බිල්ඩින්හි ප්‍රති result ලය localsසහ දේශීය විචල්‍යයක නම පසු කිරීමෙන් මෙය අවසන් වන්නේ දේශීය විචල්‍යයකට ප්‍රවේශ වීමෙනි. 3.5 වන විට පයිතන් ප්‍රලේඛනය මඟින් ශබ්ද කෝෂය වෙනස් කිරීම සාර්ථක නොවනු ඇති නමුත් එය මට වැඩ කරන බව පෙනේ.


3

පයිතන් ඒවාට අගයන් සහ යොමු කිරීම් හසුරුවන ආකාරය අනුව, ඔබට අත්තනෝමතික නිදර්ශන ලක්ෂණයක් සඳහන් කළ හැකි එකම ක්‍රමය නම් වේ:

class PassByReferenceIsh:
    def __init__(self):
        self.variable = 'Original'
        self.change('variable')
        print self.variable

    def change(self, var):
        self.__dict__[var] = 'Changed'

තාත්වික කේතයෙන් ඔබ ඇත්ත වශයෙන්ම, ඩික්ට් බැලීමේදී දෝෂ පරීක්ෂා කිරීමක් එකතු කරනු ඇත.


3

ශබ්ද කෝෂ යොමු කිරීම මඟින් සම්මත කර ඇති හෙයින්, ඔබට යොමු විචල්‍යයන් භාවිතා කර එය තුළ ඕනෑම යොමු අගයක් ගබඩා කළ හැකිය.

# returns the result of adding numbers `a` and `b`
def AddNumbers(a, b, ref): # using a dict for reference
    result = a + b
    ref['multi'] = a * b # reference the multi. ref['multi'] is number
    ref['msg'] = "The result: " + str(result) + " was nice!" # reference any string (errors, e.t.c). ref['msg'] is string
    return result # return the sum

number1 = 5
number2 = 10
ref = {} # init a dict like that so it can save all the referenced values. this is because all dictionaries are passed by reference, while strings and numbers do not.

sum = AddNumbers(number1, number2, ref)
print("sum: ", sum)             # the return value
print("multi: ", ref['multi'])  # a referenced value
print("msg: ", ref['msg'])      # a referenced value

3

පයිතන්හි පාස්-බයි-යොමු කිරීම සී ++ / ජාවා හි පාස් බයි යොමු කිරීමේ සංකල්පයට වඩා බෙහෙවින් වෙනස් ය.

  • ජාවා සහ සී #: ප්‍රාථමික වර්ග (නූල් ඇතුළත්) අගය අනුව ගමන් කරයි (පිටපත), යොමු වර්ගය යොමු කිරීම (ලිපින පිටපත) මඟින් සම්මත වේ, එබැවින් පරාමිතියෙහි සිදු කරන ලද සියලුම වෙනස්කම් ඇමතුම්කරුට දැකිය හැකිය.
  • C ++: පාස්-බයි-යොමු හෝ පාස්-බයි-අගය යන දෙකටම අවසර ඇත. පරාමිතියක් යොමු කිරීමකින් සම්මත කර ඇත්නම්, ඔබට එය වෙනස් කළ හැකිය, නැතහොත් පරාමිතිය const ලෙස සම්මත වී තිබේද නැද්ද යන්න මත පදනම්ව නොවේ. කෙසේ වෙතත්, නියත වශයෙන්ම නැතත්, පරාමිතිය වස්තුව වෙත යොමු කිරීම පවත්වා ගෙන යන අතර, හැඳින්වෙන ශ්‍රිතය තුළ වෙනත් වස්තුවක් වෙත යොමු කිරීම සඳහා යොමු කිරීම පැවරිය නොහැක.
  • පයිතන්: පයිතන් යනු “වස්තු-යොමු-පසු-යොමු කිරීම” වන අතර, බොහෝ විට එය කියනුයේ “වස්තු යොමු කිරීම් අගය අනුව සම්මත වේ” යනුවෙනි. [මෙහි කියවන්න] 1. අමතන්නා සහ ශ්‍රිතය යන දෙකම එකම වස්තුවකට යොමු වන නමුත් ශ්‍රිතයේ පරාමිතිය නව විචල්‍යයක් වන අතර එය අමතන්නා තුළ වස්තුවේ පිටපතක් තබා ගනී. C ++ මෙන්, පරාමිතියක් වෙනස් කළ හැකිය හෝ ක්‍රියාකාරී නොවේ - මෙය රඳා පවතින්නේ සම්මත කරන ලද වස්තුව මත ය. උදා; විකෘති වූ වස්තුවක් යාවත්කාලීන කිරීම හෝ නැවත ආරම්භ කිරීම කළ හැකි අතර, වෙනස් කළ නොහැකි වස්තු වර්ගයක් හැඳින්වෙන ශ්‍රිතයේ වෙනස් කළ නොහැක. විකෘති විචල්‍යය යාවත්කාලීන කිරීම හෝ නැවත පැවරීම / නැවත ආරම්භ කිරීම අතර තීරණාත්මක වෙනසක් නම්, යාවත්කාලීන කළ අගය නැවත කැඳවන ලද ශ්‍රිතය තුළ පිළිබිඹු වන අතර නැවත ආරම්භ කළ අගය එසේ නොවේ. විකෘති විචල්‍යයකට නව වස්තුවක් පැවරීමේ විෂය පථය පයිතන්හි ශ්‍රිතයට දේශීය වේ. මෙය තේරුම් ගැනීමට @ blair-conrad විසින් සපයන ලද උදාහරණ විශිෂ්ටයි.

1
පැරණි නමුත් එය නිවැරදි කිරීමට මා බැඳී සිටින බව මට හැඟේ. ජාවා සහ සී # යන දෙකින්ම නූල් යොමු කරනු ලැබේ, අගය අනුව නොවේ
ජෝන්

2

ඔබේ උදාහරණය වස්තු-නැඹුරු බැවින්, සමාන ප්‍රති result ලයක් ලබා ගැනීම සඳහා ඔබට පහත සඳහන් වෙනසක් කළ හැකිය:

class PassByReference:
    def __init__(self):
        self.variable = 'Original'
        self.change('variable')
        print(self.variable)

    def change(self, var):
        setattr(self, var, 'Changed')

# o.variable will equal 'Changed'
o = PassByReference()
assert o.variable == 'Changed'

1
මෙය ක්‍රියාත්මක වුවද. එය යොමු කිරීමකින් සම්මත නොවේ. එය 'වස්තු යොමු කිරීම හරහා ගමන් කිරීම' වේ.
බිෂ්වාස් මිශ්‍ර

1

අභ්‍යන්තර වස්තු ගුණාංග නිදර්ශන ශබ්දකෝෂයක ගබඩා කර ඇති නිසා ඔබට යොමු පංති ගබඩා කිරීම සඳහා නිදසුනක් ලෙස හිස් පන්තියක් භාවිතා කළ හැකිය . උදාහරණය බලන්න.

class RefsObj(object):
    "A class which helps to create references to variables."
    pass

...

# an example of usage
def change_ref_var(ref_obj):
    ref_obj.val = 24

ref_obj = RefsObj()
ref_obj.val = 1
print(ref_obj.val) # or print ref_obj.val for python2
change_ref_var(ref_obj)
print(ref_obj.val)

1

එය කොතැනකවත් සඳහන් කර නැති බව පෙනේ. උදා.

def need_to_modify(update):
    update(42) # set new value 42
    # other code

def call_it():
    value = 21
    def update_value(new_value):
        nonlocal value
        value = new_value
    need_to_modify(update_value)
    print(value) # prints 42

මෙය බොහෝ දුරට ප්‍රයෝජනවත් වන්නේ "පිටත පමණක් යොමු කිරීම්" සඳහා හෝ බහු නූල් / ක්‍රියාවලි සහිත තත්වයක (යාවත්කාලීන ශ්‍රිතය නූල් / බහු සැකසුම් ආරක්ෂිත කිරීම මගින්).

නිසැකවම ඉහත අගය අගය කියවීමට ඉඩ නොදේ , එය යාවත්කාලීන කිරීම පමණි.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.