ශ්‍රිතයක ගෝලීය විචල්‍යයන් භාවිතා කිරීම


3127

ශ්‍රිතයක ගෝලීය විචල්‍යයක් නිර්මාණය කරන්නේ හෝ භාවිතා කරන්නේ කෙසේද?

මම එක් ශ්‍රිතයක ගෝලීය විචල්‍යයක් නිර්මාණය කරන්නේ නම්, එම ගෝලීය විචල්‍යය වෙනත් ශ්‍රිතයක භාවිතා කරන්නේ කෙසේද? ගෝලීය විචල්‍යය එහි ප්‍රවේශය අවශ්‍ය වන ශ්‍රිතයේ දේශීය විචල්‍යයක ගබඩා කිරීමට මට අවශ්‍යද?

Answers:


4264

ඔබට globalපවරා ඇති එක් එක් ශ්‍රිතයේ මෙන් එය ප්‍රකාශ කිරීමෙන් ඔබට ගෝලීය විචල්‍යයක් වෙනත් ශ්‍රිතයන්හි භාවිතා කළ හැකිය :

globvar = 0

def set_globvar_to_one():
    global globvar    # Needed to modify global copy of globvar
    globvar = 1

def print_globvar():
    print(globvar)     # No need for global declaration to read value of globvar

set_globvar_to_one()
print_globvar()       # Prints 1

ගෝලීය විචල්‍යයන් එතරම් භයානක බැවින්, පයිතන්ට අවශ්‍ය වන්නේ ඔබ සෙල්ලම් කරන්නේ එය බව ඔබ සැබවින්ම දන්නා බව සහතික කර ගැනීමටයි global.

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


841
ග්ලෝබල් "එතරම් භයානක" ලෙස හැඳින්වීම අතිශයෝක්තියක්. මෙතෙක් පැවති සහ පවතින සෑම භාෂාවකම ග්ලෝබල් පරිපූර්ණයි. ඔවුන්ට ඔවුන්ගේ ස්ථානය තිබේ. ඔබ පැවසිය යුතු දෙය නම් ඔබට ක්‍රමලේඛනය කරන්නේ කෙසේද යන්න පිළිබඳ හෝඩුවාවක් නොමැති නම් ඒවා ගැටළු ඇති කළ හැකිය.
ඇන්තනි

209
මම හිතන්නේ ඒවා තරමක් භයානකයි. කෙසේ වෙතත්, පයිතන්හි "ගෝලීය" විචල්‍යයන් ඇත්ත වශයෙන්ම මොඩියුල මට්ටමේ වන අතර එමඟින් ගැටලු රාශියක් විසඳනු ලැබේ.
ෆේබියෝ සැන්ටොස්

248
පයිතන්ට globalමූලික පදය අවශ්‍ය වීමට හේතුව ගෝලීය භයානක නිසා බව මම එකඟ නොවෙමි . ඒ වෙනුවට, එයට හේතුව ඔබ විසින් විචල්‍යයන් පැහැදිලිව ප්‍රකාශ කිරීම අවශ්‍ය නොවන අතර ඔබ පවරා ඇති විචල්‍යයකට ඔබ වෙනත් ආකාරයකින් නොකියන්නේ නම් එය ක්‍රියාකාරී විෂය පථයක් ඇති බව ස්වයංක්‍රීයව උපකල්පනය කරයි. මෙම globalමූල පදය වෙනත් ආකාරයකින් එය කියන්න සපයනු ලබන බව ස්ථිරයි.
නේට් සීකේ

7
gavgvstvs: තවද ඔබ එකම වැඩසටහනක් ග්ලෝබල් නොමැතිව ක්‍රියාත්මක කරන්නේ නම්, ඔබට තවමත් එකම කේත මාර්ග ගණනක් ඇත. ඔබ ඉදිරිපත් කළ තර්කය ගෝලීයයන්ට එරෙහි එකක් නොවේ.
කක්ෂයේ සැහැල්ලු ධාවන තරඟ

13
IghtLightnessRacesinOrbit මට ඔබේ අදහස තේරෙන්නේ නැත. ඔබ ගෝලීය විචල්‍යයක් ඉවත් කරන්නේ නම්, දැන් ඔබ එහි ඇති සංකීර්ණ සාධකය ඉවත් කරයි, අත්තනෝමතික ශ්‍රිතයන්ට තවදුරටත් ක්‍රියාත්මක වීමේ විවිධ අවස්ථා වලදී වැඩසටහන් තත්වය වෙනස් කළ නොහැක - එමඟින් එම විචල්‍යය මත රඳා පවතින වෙනත් ශ්‍රිතයන්ට වෙනත් ආකාරයකින් නොපෙනෙන අයුරින් ක්‍රියාත්මක කිරීම වෙනස් කරයි. " f2()තත්වය වෙනස් කිරීම නිසා දැන් f3()අනපේක්ෂිත දෙයක් කළ හැකිද? කාර්යයන් වලට දැන් අ
nost ෙයවාදීන්

776

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

ඔබට මේ වගේ මොඩියුලයක් ඇති බව පවසන්න:

# sample.py
myGlobal = 5

def func1():
    myGlobal = 42

def func2():
    print myGlobal

func1()
func2()

ඔබ මෙම 42 මුද්රණය කිරීමට බලාපොරොත්තු විය හැකිය, එහෙත් ඒ වෙනුවට ඔහු කෙළේ, එය 5. ඔබ 'එකතු කරන්න නම්, මේ වන විටත් සඳහන් කර ඇත මුද්රණය globalසඳහා' ප්රකාශ func1()එසේ නම්, func2()42 මුද්රණය කරනු ඇත.

def func1():
    global myGlobal
    myGlobal = 42

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

ඔබ නමට 42 ක් පවරන විට myGlobal, එම නාමයේ ගෝලීය විචල්‍යයට සෙවන සපයන දේශීය විචල්‍යයක් පයිතන් විසින් නිර්මාණය කරයි. එම ප්‍රදේශය විෂය පථයෙන් බැහැරව ආපසු පැමිණෙන විට කසළ එකතු කරනු ලැබේfunc1() ; මේ අතර, func2()(නවීකරණය නොකළ) ගෝලීය නාමය හැර වෙනත් කිසිවක් දැකිය නොහැක. මෙම නාම අවකාශයේ තීරණය සිදුවන්නේ ධාවන වේලාවේදී නොව සංයුක්ත වේලාවක බව සලකන්න - ඔබ එය පැවරීමට පෙර myGlobalඇතුළත වටිනාකම කියවා func1()බැලුවහොත් ඔබට එය ලැබෙනු ඇත UnboundLocalError, මන්ද එය දේශීය විචල්‍යයක් විය යුතු බව පයිතන් දැනටමත් තීරණය කර ඇති නමුත් එය තවම ඒ හා සම්බන්ධ කිසිදු වටිනාකමක් නොමැත. නමුත් ' global' ප්‍රකාශය භාවිතා කිරීමෙන් , ඔබ පයිතන්ට පවසන්නේ එය දේශීයව පැවරීම වෙනුවට නම සඳහා වෙනත් තැනක බැලිය යුතු බවයි.

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


නාම අවකාශයේ තීරණය සම්පාදනය කරන වේලාවේදී සිදුවන බව ඔබ සඳහන් කළ අතර එය සත්‍ය යැයි මම නොසිතමි. මම ඉගෙන ගන්නා දෙයින් පයිතන්ගේ සම්පාදනය සින්ටැක්ස් දෝෂය සඳහා පමණක් පරික්ෂා කරයි, නම දෝෂයක් නොවේ මෙම උදාහරණය උත්සාහ කරන්න def A (): x + = 1 , ඔබ එය ක්‍රියාත්මක නොකරන්නේ නම්, එය UnboundLocalError ලබා නොදෙනු ඇත , කරුණාකර ස්තූතියි සත්‍යාපනය කරන්න
watashiSHUN

1
ගෝලීය විචල්‍යයන් සඳහා ලොකු අකුරක් භාවිතා කිරීම සාමාන්‍ය දෙයකිMyGlobal = 5
Vassilis

3
@watashiSHUN: මෙම නාමඅවකාශයෙහි තීරණය කරන්නේ බැදීමකට වෙනවා. xඑය දේශීය යැයි තීරණය කිරීම පළමු වරට භාවිතා කිරීමට පෙර දේශීය නම අගයකට බැඳී ඇත්දැයි ධාවන වේලාවේදී පරීක්ෂා කිරීමට වඩා වෙනස් වේ.
බ්ලැක් ජැක්

9
Ass වාසිලිස්: සියලුම අකුරු ලොකු අකුරට පොදු වේ : MY_GLOBAL = 5. පයිතන් කේතය සඳහා මෝස්තර මාර්ගෝපදේශය බලන්න .
බ්ලැක් ජැක්

223

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

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

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

තනි වැඩසටහනක් තුළ මොඩියුල හරහා තොරතුරු හුවමාරු කර ගැනීමේ කැනොනිකල් ක්‍රමය නම් විශේෂ වින්‍යාස මොඩියුලයක් නිර්මාණය කිරීමයි (බොහෝ විට එය වින්‍යාසය හෝ සීඑෆ්ජී ලෙස හැඳින්වේ ). ඔබගේ යෙදුමේ සියලුම මොඩියුලවල වින්‍යාස මොඩියුලය ආයාත කරන්න; පසුව මොඩියුලය ගෝලීය නාමයක් ලෙස ලබා ගත හැකිය. එක් එක් මොඩියුලයේ එක් අවස්ථාවක් පමණක් ඇති හෙයින්, මොඩියුලයේ වස්තුවෙහි සිදුකරන ඕනෑම වෙනස්කමක් සෑම තැනකම පිළිබිඹු වේ. උදාහරණයක් වශයෙන්:

ගොනුව: config.py

x = 0   # Default value of the 'x' configuration setting

ගොනුව: mod.py

import config
config.x = 1

ගොනුව: main.py

import config
import mod
print config.x

1
හේතුවක් නැති නිසා මට config.x එය ඉවත් කළ හැකිද? මම ආවා x = lambda: config.x, පසුව මට නව වටිනාකමක් තිබේ x(). කිසියම් හේතුවක් නිසා, තිබීම a = config.xමා වෙනුවෙන් උපක්‍රමයක් නොකරයි.
vladosaurus

3
lavladosaurus එය විසඳයිද from config import x?
ජිලන්ඩ්ස්

93

දේශීය හා ගෝලීය අතර විචල්‍යයක් පැටවිය යුත්තේ කුමන විෂය පථයෙන්ද යන්න තීරණය කිරීම සඳහා පයිතන් සරල ur ෂධයක් භාවිතා කරයි. පැවරුමක වම් පස විචල්‍ය නාමයක් දිස් වුවද එය ගෝලීය ලෙස ප්‍රකාශයට පත් නොකෙරේ නම් එය දේශීය යැයි උපකල්පනය කෙරේ. පැවරුමක වම් පසින් එය නොපෙන්වන්නේ නම්, එය ගෝලීය යැයි උපකල්පනය කෙරේ.

>>> import dis
>>> def foo():
...     global bar
...     baz = 5
...     print bar
...     print baz
...     print quux
... 
>>> dis.disassemble(foo.func_code)
  3           0 LOAD_CONST               1 (5)
              3 STORE_FAST               0 (baz)

  4           6 LOAD_GLOBAL              0 (bar)
              9 PRINT_ITEM          
             10 PRINT_NEWLINE       

  5          11 LOAD_FAST                0 (baz)
             14 PRINT_ITEM          
             15 PRINT_NEWLINE       

  6          16 LOAD_GLOBAL              1 (quux)
             19 PRINT_ITEM          
             20 PRINT_NEWLINE       
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE        
>>> 

පැවරුමක වම්පස දිස්වන බාස් foo()එකම LOAD_FASTවිචල්‍යය වන්නේ කෙසේදැයි බලන්න .


12
බන්ධන මෙහෙයුම් සඳහා හියුරිස්ටික් සොයයි . පැවරුම යනු එවැනි එක් මෙහෙයුමක් වන අතර තවත් එකක් ආනයනය කිරීමයි. නමුත් ඒ ඉලක්කය forපසු ලූපය සහ නම asදී withහා exceptප්රකාශ කිරීමට ද බැඳී ඇත.
මාර්ටිජන් පීටර්ස්

පසු නම සඳහා @MartijnPieters asතුළ සිටින exceptමෙම වූයේ මට ද පැහැදිලි නැත වගන්තිය. නමුත් මතකය සුරැකීම සඳහා එය ස්වයංක්‍රීයව මකා දමනු ලැබේ.
රොබට්

1
Ob රොබට්: මතකය සුරැකීමට නොව, මතක කාන්දුවීම් වලට තුඩු දිය හැකි රවුම් යොමු කිරීමක් වළක්වා ගැනීමට. එයට හේතුව ව්‍යතිරේකයක් මඟින් ලුහුබැඳීමක් ගැන සඳහන් වන අතර, ලුහුබැඳීම් සෑම දේශීය හා ගෝලීය නාම අවකාශයක්ම සමස්ත ඇමතුම් තොගය දිගේ සඳහන් කරයි as ....
මාර්ටිජන් පීටර්ස්

62

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

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

එසේම, වෙනත් OOP ජ්වලිතයන්ට පටහැනිව ගෝලීය විචල්‍යයන් ප්‍රයෝජනවත් වේ - විශේෂයෙන් කුඩා පිටපත් සඳහා, OOP අධික ලෙස මරණයට පත් වේ.


නියත වශයෙන්ම නැවත. ජ්වලිතයන්. බොහෝ පයිතන් භාවිතා කරන්නන් එය ස්ක්‍රිප්ටින් සඳහා භාවිතා කරන අතර කුඩා කේත වෙන් කිරීමට කුඩා කාර්යයන් නිර්මාණය කරයි.
පෝල් උස්සාක්

51

මම එක් ශ්‍රිතයක ගෝලීය විචල්‍යයක් නිර්මාණය කරන්නේ නම්, එම ශ්‍රිතය වෙනත් ශ්‍රිතයක භාවිතා කරන්නේ කෙසේද?

පහත දැක්වෙන ශ්‍රිතය සමඟ අපට ගෝලීය නිර්මාණය කළ හැකිය:

def create_global_variable():
    global global_variable # must declare it to be a global first
    # modifications are thus reflected on the module's global scope
    global_variable = 'Foo' 

ශ්‍රිතයක් ලිවීම ඇත්ත වශයෙන්ම එහි කේතය ක්‍රියාත්මක නොකරයි. එබැවින් අපි create_global_variableශ්‍රිතය ලෙස හඳුන්වමු :

>>> create_global_variable()

වෙනස් කිරීමකින් තොරව ග්ලෝබල් භාවිතා කිරීම

ඔබට එය භාවිතා කළ හැකිය, එය යොමු කරන වස්තුව වෙනස් කිරීමට ඔබ අපේක්ෂා නොකරන තාක් කල්:

උදාහරණයක් වශයෙන්,

def use_global_variable():
    return global_variable + '!!!'

දැන් අපට ගෝලීය විචල්‍යය භාවිතා කළ හැකිය:

>>> use_global_variable()
'Foo!!!'

ශ්‍රිතයක් තුළ සිට ගෝලීය විචල්‍යය වෙනස් කිරීම

ගෝලීය විචල්‍යය වෙනත් වස්තුවකට යොමු කිරීම සඳහා, ඔබ නැවත ගෝලීය මූල පදය භාවිතා කළ යුතුය:

def change_global_variable():
    global global_variable
    global_variable = 'Bar'

මෙම ශ්‍රිතය ලිවීමෙන් පසුව, ඇත්ත වශයෙන්ම එය වෙනස් කරන කේතය තවමත් ක්‍රියාත්මක නොවන බව සලකන්න.

>>> use_global_variable()
'Foo!!!'

එබැවින් ශ්‍රිතය ඇමතීමෙන් පසු:

>>> change_global_variable()

ගෝලීය විචල්‍යය වෙනස් කර ඇති බව අපට පෙනේ. මෙම global_variableනම දැන් පෙන්නුම් 'Bar':

>>> use_global_variable()
'Bar!!!'

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

එකම නම සහිත දේශීය විචල්යයන්

ඔබ එකම නමින් දේශීය විචල්‍යයක් නිර්මාණය කරන්නේ නම්, එය ගෝලීය විචල්‍යයක් යටපත් කරනු ඇත:

def use_local_with_same_name_as_global():
    # bad name for a local variable, though.
    global_variable = 'Baz' 
    return global_variable + '!!!'

>>> use_local_with_same_name_as_global()
'Baz!!!'

නමුත් වැරදි ලෙස නම් කරන ලද දේශීය විචල්‍යය භාවිතා කිරීමෙන් ගෝලීය විචල්‍යය වෙනස් නොවේ:

>>> use_global_variable()
'Bar!!!'

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

පංති වලදී අපට එකම හැසිරීම ලැබේ

අදහස් දැක්වීම පිළිබඳ පසු විපරමක් අසයි:

පංතියක් තුළ ශ්‍රිතයක් තුළ ගෝලීය විචල්‍යයක් නිර්මාණය කිරීමට සහ වෙනත් පන්තියක් තුළ වෙනත් ශ්‍රිතයක් තුළ එම විචල්‍යය භාවිතා කිරීමට අවශ්‍ය නම් කුමක් කළ යුතුද?

මෙහිදී මම නිරූපණය කරන්නේ අප නිත්‍ය කාර්යයන් වලදී කරන ආකාරයටම ක්‍රමවේදයන් අනුගමනය කරන බවයි:

class Foo:
    def foo(self):
        global global_variable
        global_variable = 'Foo'

class Bar:
    def bar(self):
        return global_variable + '!!!'

Foo().foo()

සහ දැන්:

>>> Bar().bar()
'Foo!!!'

නමුත් මොඩියුලයේ නාම අවකාශය අවුල් නොකිරීමට ඔබ පන්ති ලක්ෂණ භාවිතා කරන ගෝලීය විචල්‍යයන් භාවිතා කරනවා වෙනුවට මම යෝජනා කරමි. අප selfමෙහි තර්ක භාවිතා නොකරන බව සලකන්න - මේවා පන්ති ක්‍රම විය හැකිය (සුපුරුදු clsතර්කයෙන් පන්ති ගුණාංග විකෘති කරන්නේ නම් පහසුය ) හෝ ස්ථිතික ක්‍රම (නැත selfහෝ cls).


සිසිල්, නමුත් මට පන්තියක් තුළ ශ්‍රිතයක් තුළ ගෝලීය විචල්‍යයක් නිර්මාණය කිරීමට අවශ්‍ය නම් සහ වෙනත් පන්තියක් තුළ වෙනත් ශ්‍රිතයක් තුළ එම විචල්‍යය භාවිතා කිරීමට අවශ්‍ය නම් කුමක් කළ යුතුද?
කරුණාව

2
onanonmanx ඔබ හිර වී සිටින්නේ මන්දැයි මම නොදනිමි, එය සාමාන්‍ය ශ්‍රිතයක මෙන් එකම හැසිරීමකි. නමුත් මම ඔබේ ප්‍රකාශය සහ සමහර ඩිමෝ කේත සමඟ මගේ පිළිතුර යාවත්කාලීන කරමි, හරිද?
ආරොන් හෝල්

1
@anonmanx කොහොමද ඒක?
ආරොන් හෝල්

හරි, තේරුණා. එබැවින් එම ගෝලීය විචල්‍යය භාවිතා කිරීම සඳහා මට එම ශ්‍රිතය පැහැදිලිව ඇමතීමට සිදුවේ.
anonmanx

47

දැනටමත් පවතින පිළිතුරු වලට අමතරව මෙය වඩාත් ව්‍යාකූල කිරීමට:

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

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

මූලාශ්‍රය: පයිතන්හි දේශීය හා ගෝලීය විචල්‍යයන් සඳහා වන නීති මොනවාද? .


34

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

import multiprocessing
import os
import random
import sys
import time

def worker(new_value):
    old_value = get_value()
    set_value(random.randint(1, 99))
    print('pid=[{pid}] '
          'old_value=[{old_value:2}] '
          'new_value=[{new_value:2}] '
          'get_value=[{get_value:2}]'.format(
          pid=str(os.getpid()),
          old_value=old_value,
          new_value=new_value,
          get_value=get_value()))

def get_value():
    global global_variable
    return global_variable

def set_value(new_value):
    global global_variable
    global_variable = new_value

global_variable = -1

print('before set_value(), get_value() = [%s]' % get_value())
set_value(new_value=-2)
print('after  set_value(), get_value() = [%s]' % get_value())

processPool = multiprocessing.Pool(processes=5)
processPool.map(func=worker, iterable=range(15))

ප්‍රතිදානය:

before set_value(), get_value() = [-1]
after  set_value(), get_value() = [-2]
pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
pid=[53973] old_value=[94] new_value=[10] get_value=[87]
pid=[53970] old_value=[21] new_value=[11] get_value=[21]
pid=[53971] old_value=[34] new_value=[12] get_value=[82]
pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
pid=[53973] old_value=[87] new_value=[14] get_value=[70]

25

ඔබ කියන්නේ මේ ක්‍රමය භාවිතා කිරීමයි:

globvar = 5

def f():
    var = globvar
    print(var)

f()  # Prints 5

නමුත් වඩා හොඳ ක්‍රමය වන්නේ ගෝලීය විචල්‍යය මේ ආකාරයෙන් භාවිතා කිරීමයි:

globavar = 5
def f():
    global globvar
    print(globvar)
f()   #prints 5

දෙකම එකම ප්රතිදානය ලබා දෙයි.


25

පෙනෙන පරිදි පිළිතුර සෑම විටම සරල ය.

mainඅර්ථ දැක්වීමකින් එය පෙන්වීමට සරල ක්‍රමයක් සහිත කුඩා නියැදි මොඩියුලයක් මෙන්න :

def five(enterAnumber,sumation):
    global helper
    helper  = enterAnumber + sumation

def isTheNumber():
    return helper

mainඅර්ථ දැක්වීමකින් එය පෙන්විය යුතු ආකාරය මෙන්න :

import TestPy

def main():
    atest  = TestPy
    atest.five(5,8)
    print(atest.isTheNumber())

if __name__ == '__main__':
    main()

මෙම සරල කේතය ඒ ආකාරයටම ක්‍රියාත්මක වන අතර එය ක්‍රියාත්මක වනු ඇත. එය උපකාරී වේ යැයි මම බලාපොරොත්තු වෙමි.


1
ස්තූතියි, මම පයිතන්ට අලුත්, නමුත් ටිකක් ජාවා දන්නවා. ඔයා කියපු දේ මට වැඩ කළා. පංතිය තුළ ගෝලීය <ENTER> ලිවීම .. 'ග්ලෝබල් අ' ලිවීමේ ශ්‍රිතයකට වඩා මට තේරුමක් ඇති බව පෙනේ .. ඔබට ගෝලීය a = 4
බාර්ලොප්

2
මෙය මට සරලම නමුත් ඉතා ප්‍රයෝජනවත් පයිතන් උපක්‍රමයක් විය හැකිය. මම මෙම මොඩියුලය නම් කර ආරම්භක ස්ක්‍රිප්ටයේ global_varsදත්ත init_global_varsකැඳවීම ආරම්භ කරමි. ඉන්පසුව, මම එක් එක් නිර්වචනය කළ ගෝලීය var සඳහා ප්‍රවේශක ක්‍රමයක් නිර්මාණය කරමි. මට මෙය කිහිප වතාවක්ම ඉහළ නැංවිය හැකි යැයි මම විශ්වාස කරමි! ස්තූතියි පීටර්!
swdev

1
ගෝලීය විචල්‍යයන් බොහොමයක් තිබේ නම් සහ ගෝලීය ප්‍රකාශයකින් පසු ඒවා එකින් එක ලැයිස්තු ගත කිරීමට මට අවශ්‍ය නොවන්නේ නම් කුමක් කළ යුතුද?
jtlz2

23

ඔබට භාවිතා කිරීමට අවශ්‍ය සෑම ශ්‍රිතයකම ගෝලීය විචල්‍යය සඳහන් කළ යුතුය.

පහත පරිදි:

var = "test"

def printGlobalText():
    global var #wWe are telling to explicitly use the global version
    var = "global from printGlobalText fun."
    print "var from printGlobalText: " + var

def printLocalText():
    #We are NOT telling to explicitly use the global version, so we are creating a local variable
    var = "local version from printLocalText fun"
    print "var from printLocalText: " + var

printGlobalText()
printLocalText()
"""
Output Result:
var from printGlobalText: global from printGlobalText fun.
var from printLocalText: local version from printLocalText
[Finished in 0.1s]
"""

3
'ඔබට භාවිතා කිරීමට අවශ්‍ය සෑම
ශ්‍රිතයකම

21

ඔබ ඇත්ත වශයෙන්ම ගෝලීය දේශීය විචල්‍යයක ගබඩා නොකරන්නේ, ඔබේ මුල් ගෝලීය යොමුව සඳහන් කරන එකම වස්තුවට දේශීය යොමු කිරීමක් නිර්මාණය කිරීමෙනි. පයිතන්හි ඇති සෑම දෙයක්ම වස්තුවකට යොමු වන නමක් බව මතක තබා ගන්න, සුපුරුදු ක්‍රියාකාරිත්වයේ කිසිවක් පිටපත් නොවේ.

හදුනාගැනීමක් පූර්ව නිශ්චිත ගෝලීය වෙත යොමු කිරීමට ඔබට නිශ්චිතවම සඳහන් කිරීමට අවශ්‍ය නොවූයේ නම්, ඒ වෙනුවට හඳුනාගැනීමක් නව දේශීය විචල්‍යයක් වන විට ඔබ පැහැදිලිවම සඳහන් කළ යුතුය (නිදසුනක් ලෙස, 'var' විධානය වැනි දෙයක් සමඟ ජාවාස්ක්‍රිප්ට් හි දැකිය හැක). ඕනෑම බැරෑරුම් හා සුළු නොවන පද්ධතියක ගෝලීය විචල්‍යයන්ට වඩා දේශීය විචල්‍යයන් බහුලව පවතින හෙයින්, පයිතන්ගේ ක්‍රමය බොහෝ අවස්ථාවන්හි දී වඩාත් අර්ථවත් කරයි.

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


17

මේක උත්සාහ කරන්න:

def x1():
    global x
    x = 6

def x2():
    global x
    x = x+1
    print x

x = 5
x1()
x2()  # output --> 7


14

පහත දැක්වෙන පරිදි සහ එකතු කිරීමක් ලෙස, දේශීයව ප්‍රකාශයට පත් කර ඇති සියලුම ගෝලීය විචල්‍යයන් අඩංගු කිරීමට ගොනුවක් භාවිතා කරන්න import as:

ගොනුව initval.py :

Stocksin = 300
Prices = []

ගොනුව getstocks.py :

import initval as iv

def getmystocks(): 
    iv.Stocksin = getstockcount()


def getmycharts():
    for ic in range(iv.Stocksin):

1
ගෝලීය විචල්‍යයන් වෙනත් ගොනුවකට ගෙන යාමේ වාසිය කුමක්ද? කුඩා ගොනුවක ගෝලීය විචල්‍යයන් එකට එකතු කිරීම පමණක්ද? ප්‍රකාශය භාවිතා කරන්නේ ඇයි import ... as ...? ඇයි නැත්තේ import ...?
ඔලිබ්‍රේ

1
අහ් ... මම අවසාන වශයෙන් වාසිය තේරුම් ගෙන ඇත්තෙමි: මූල පදය භාවිතා කිරීමට අවශ්‍ය නැත global:-) => +1 :-) අනෙක් පුද්ගලයින්ට ඇති විය හැකි මෙම ප්‍රශ්න කිරීම් පැහැදිලි කිරීමට කරුණාකර ඔබේ පිළිතුර සංස්කරණය කරන්න. චියර්ස්
ඔලිබ්රේ

13

ගෝලීය අරාවෙහි පැහැදිලි අංග වෙත ලිවීමට ගෝලීය ප්‍රකාශනය අවශ්‍ය නොවන බව පෙනේ. “තොග” වෙත ලිවීමට එම අවශ්‍යතාවය ඇත:

import numpy as np

hostValue = 3.14159
hostArray = np.array([2., 3.])
hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])

def func1():
    global hostValue    # mandatory, else local.
    hostValue = 2.0

def func2():
    global hostValue    # mandatory, else UnboundLocalError.
    hostValue += 1.0

def func3():
    global hostArray    # mandatory, else local.
    hostArray = np.array([14., 15.])

def func4():            # no need for globals
    hostArray[0] = 123.4

def func5():            # no need for globals
    hostArray[1] += 1.0

def func6():            # no need for globals
    hostMatrix[1][1] = 12.

def func7():            # no need for globals
    hostMatrix[0][0] += 0.33

func1()
print "After func1(), hostValue = ", hostValue
func2()
print "After func2(), hostValue = ", hostValue
func3()
print "After func3(), hostArray = ", hostArray
func4()
print "After func4(), hostArray = ", hostArray
func5()
print "After func5(), hostArray = ", hostArray
func6()
print "After func6(), hostMatrix = \n", hostMatrix
func7()
print "After func7(), hostMatrix = \n", hostMatrix

7

වෙනත් කිසිදු පිළිතුරකින් මා දැක නැති නිසා මම මෙය එකතු කරමි. ඒ හා සමාන දෙයක් සමඟ පොරබදින කෙනෙකුට එය ප්‍රයෝජනවත් විය හැකිය. මෙම globals()කාර්යය සඳහා mutable ගෝලීය සංකේතය ශබ්ද කෝෂය ඔබ ", භූගෝලීය පිහිටීම" ඔබගේ කේතය ඉතිරි පසුබිම දත්ත ලබා ගත හැකි පැමිණේ. උදාහරණයක් වශයෙන්:

from pickle import load
def loaditem(name):
    with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
        globals()[name] = load(openfile)
    return True

හා

from pickle import dump
def dumpfile(name):
    with open(name+".dat", "wb") as outfile:
        dump(globals()[name], outfile)
    return True

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


3
globals()සෑම විටම දේශීය සන්දර්භය තුළ ඇති ග්ලෝබල් ලබා දෙයි, එබැවින් මෙහි විකෘතියක් වෙනත් මොඩියුලයක පිළිබිඹු නොවනු ඇත.
කිරාන් ජොනලගද්ද

6

වෙනස පෙන්වීමට ඔබට අවශ්‍ය පන්තියේ නාම අවකාශය යොමු කරන්න.

මෙම උදාහරණයේ දී, ධාවකය වින්‍යාස ගොනු වලින් උපරිම භාවිතා කරයි. මගේ පරීක්ෂණය දුවන්නා එය භාවිතා කරන විට උපරිම අගය වෙනස් කිරීමට මට අවශ්‍යය .

main / config.py

max = 15000

main / runner.py

from main import config
def check_threads():
    return max < thread_count 

පරීක්ෂණ / runner_test.py

from main import runner                # <----- 1. add file
from main.runner import check_threads
class RunnerTest(unittest):
   def test_threads(self):
       runner.max = 0                  # <----- 2. set global 
       check_threads()

1

ග්ලෝබල් හොඳයි - බහු සැකසුම් හැර

එක් පැත්තකින් වින්ඩෝස් / මැක් ඕඑස් ලෙස විවිධ වේදිකා / පරිසරයන්හි බහු සැකසුම් සම්බන්ධව ග්ලෝබල් සහ අනෙක් පැත්තෙන් ලිනක්ස් කරදරකාරී ය.

කලකට පෙර මා මුහුණ දුන් ගැටලුවක් පෙන්වා දෙන සරල උදාහරණයකින් මම මෙය ඔබට පෙන්වන්නම්.

ඔබට තේරුම් ගැනීමට අවශ්‍ය නම්, වින්ඩෝස් / මැකෝ සහ ලිනක්ස් වල දේවල් වෙනස් වන්නේ ඇයිදැයි ඔබ දැනගත යුතුය, නව ක්‍රියාවලියක් ආරම්භ කිරීමේ පෙරනිමි යාන්ත්‍රණය ...

  • වින්ඩෝස් / මැකෝ යනු 'ස්පොන්' ය
  • ලිනක්ස් යනු 'දෙබලක' ය

මතක වෙන්කිරීමේ ආරම්භයේදී ඒවා වෙනස් වේ ... (නමුත් මම මෙතැනට නොයමි).

ගැටලුව / උදාහරණය දෙස බලමු ...

import multiprocessing

counter = 0

def do(task_id):
    global counter
    counter +=1
    print(f'task {task_id}: counter = {counter}')

if __name__ == '__main__':

    pool = multiprocessing.Pool(processes=4)
    task_ids = list(range(4))
    pool.map(do, task_ids)

වින්ඩෝස්

ඔබ මෙය වින්ඩෝස් මත ධාවනය කරන්නේ නම් (මම මැකෝස් හි ද සිතමි), ඔබට පහත ප්‍රතිදානය ලැබේ ...

task 0: counter = 1
task 1: counter = 2
task 2: counter = 3
task 3: counter = 4

ලිනක්ස්

ඔබ මෙය ලිනක්ස් මත ධාවනය කරන්නේ නම්, ඒ වෙනුවට ඔබට පහත දේ ලැබේ.

task 0: counter = 1
task 1: counter = 1
task 2: counter = 1
task 3: counter = 1
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.