ฉันจะสร้างหรือใช้ตัวแปรโกลบอลในฟังก์ชันได้อย่างไร
ถ้าฉันสร้างตัวแปรโกลบอลในฟังก์ชันหนึ่งฉันจะใช้ตัวแปรโกลบอลนั้นในฟังก์ชันอื่นได้อย่างไร ฉันต้องจัดเก็บตัวแปรโกลบอลในตัวแปรโลคัลของฟังก์ชันที่ต้องการเข้าถึงหรือไม่?
ฉันจะสร้างหรือใช้ตัวแปรโกลบอลในฟังก์ชันได้อย่างไร
ถ้าฉันสร้างตัวแปรโกลบอลในฟังก์ชันหนึ่งฉันจะใช้ตัวแปรโกลบอลนั้นในฟังก์ชันอื่นได้อย่างไร ฉันต้องจัดเก็บตัวแปรโกลบอลในตัวแปรโลคัลของฟังก์ชันที่ต้องการเข้าถึงหรือไม่?
คำตอบ:
คุณสามารถใช้ตัวแปรโกลบอลในฟังก์ชั่นอื่น ๆ โดยการประกาศดังเช่น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
ฉันจินตนาการเหตุผลว่าเป็นเพราะตัวแปรทั่วโลกอันตรายมาก Python ต้องการให้แน่ใจว่าคุณรู้จริง ๆ ว่านั่นคือสิ่งที่คุณกำลังเล่นด้วยโดยต้องการglobal
คำหลักอย่างชัดเจน
ดูคำตอบอื่น ๆ หากคุณต้องการแชร์ตัวแปรโกลบอลข้ามโมดูล
global
คำหลักก็เพราะ globals เป็นอันตราย แต่เป็นเพราะภาษาไม่ต้องการให้คุณประกาศตัวแปรอย่างชัดเจนและถือว่าตัวแปรที่คุณกำหนดนั้นมีขอบเขตฟังก์ชั่นโดยอัตโนมัติเว้นแต่คุณจะบอกเป็นอย่างอื่น global
คำหลักเป็นวิธีการที่ให้ไว้จะบอกว่ามันเป็นอย่างอื่น
f2()
เปลี่ยนสถานะดังนั้นตอนนี้f3()
อาจทำสิ่งที่ไม่คาดคิดตอนนี้ฟังก์ชั่นสามารถทำงานได้ไม่เชื่อเรื่องพระเจ้ากับสถานะโปรแกรมภายนอก
ถ้าฉันเข้าใจสถานการณ์ของคุณอย่างถูกต้องสิ่งที่คุณเห็นคือผลลัพธ์ที่ Python จัดการกับเนมสเปซในพื้นที่ (ฟังก์ชัน) และโกลบอล (โมดูล)
สมมติว่าคุณมีโมดูลเช่นนี้:
# 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
สิ่งที่เกิดขึ้นในที่นี้คือ Python สันนิษฐานว่าชื่อใด ๆ ที่ได้รับมอบหมายในตำแหน่งใด ๆ ภายในฟังก์ชั่นนั้นเป็นของท้องถิ่นของฟังก์ชั่นนั้น หากเป็นเพียงการอ่านจากชื่อและไม่มีชื่ออยู่ภายในเครื่องจะพยายามค้นหาชื่อในขอบเขตที่มีอยู่ (เช่นขอบเขตทั่วโลกของโมดูล)
เมื่อคุณกำหนด 42 ให้กับชื่อmyGlobal
ดังนั้น Python จะสร้างตัวแปรท้องถิ่นที่จะเงาตัวแปรทั่วโลกในชื่อเดียวกัน โลคัลนั้นออกนอกขอบเขตและเก็บขยะเมื่อfunc1()
ส่งคืน ในขณะเดียวกันfunc2()
ไม่สามารถเห็นสิ่งอื่นใดนอกจากชื่อโกลบอล (ไม่แก้ไข) โปรดทราบว่าการตัดสินใจเนมสเปซนี้เกิดขึ้น ณ เวลารวบรวมไม่ใช่ในช่วงรันไทม์หากคุณต้องอ่านค่าmyGlobal
ด้านในfunc1()
ก่อนที่คุณจะกำหนดคุณจะได้รับUnboundLocalError
เนื่องจาก Python ได้ตัดสินใจแล้วว่ามันจะต้องเป็นตัวแปรในตัวเครื่อง ยังไม่ได้มีค่าใด ๆ ที่เกี่ยวข้อง แต่ด้วยการใช้global
คำสั่ง '' คุณจะบอก Python ว่าควรหาชื่ออื่นแทนการกำหนดไว้ในเครื่อง
(ฉันเชื่อว่าพฤติกรรมนี้เกิดขึ้นส่วนใหญ่ผ่านการเพิ่มประสิทธิภาพของเนมสเปซในพื้นที่ - หากไม่มีพฤติกรรมนี้ VM ของ Python จะต้องดำเนินการค้นหาชื่ออย่างน้อยสามครั้งในแต่ละครั้งที่มีการกำหนดชื่อใหม่ให้ภายในฟังก์ชัน (เพื่อให้แน่ใจว่า มีอยู่แล้วที่ระดับโมดูล / builtin) ซึ่งจะทำให้การทำงานทั่วไปเป็นไปอย่างช้าๆ)
MyGlobal = 5
x
เป็นโลคัลแตกต่างจากการตรวจสอบที่รันไทม์หากชื่อโลคัลถูกผูกไว้กับค่าก่อนที่จะถูกใช้ในครั้งแรก
คุณอาจต้องการที่จะสำรวจความคิดของnamespaces ใน Python โมดูลเป็นที่นิยมสำหรับข้อมูลทั่วโลก :
แต่ละโมดูลมีตารางสัญลักษณ์ส่วนตัวซึ่งใช้เป็นตารางสัญลักษณ์ทั่วโลกโดยฟังก์ชั่นทั้งหมดที่กำหนดไว้ในโมดูล ดังนั้นผู้เขียนของโมดูลสามารถใช้ตัวแปรทั่วโลกในโมดูลโดยไม่ต้องกังวลเกี่ยวกับการปะทะโดยไม่ตั้งใจกับตัวแปรทั่วโลกของผู้ใช้
modname.itemname
ในทางตรงกันข้ามถ้าคุณรู้ว่าสิ่งที่คุณทำคุณสามารถสัมผัสตัวแปรทั่วโลกโมดูลที่มีสัญกรณ์เดียวกับที่ใช้ในการอ้างถึงฟังก์ชั่นของมัน
การใช้งาน Global-in-a-module เฉพาะอธิบายไว้ที่นี่ - ฉันจะแชร์ตัวแปรทั่วทั้งโมดูลได้อย่างไร และเพื่อความสมบูรณ์ของเนื้อหาจะถูกแชร์ที่นี่:
วิธีมาตรฐานของการแบ่งปันข้อมูลระหว่างโมดูลภายในโปรแกรมเดียวคือการสร้างโมดูลการกำหนดค่าพิเศษ (มักเรียกว่าconfigหรือcfg ) เพียงนำเข้าโมดูลการกำหนดค่าในทุกโมดูลของแอปพลิเคชันของคุณ โมดูลนั้นพร้อมใช้งานเป็นชื่อส่วนกลาง เนื่องจากมีเพียงหนึ่งอินสแตนซ์ของแต่ละโมดูลการเปลี่ยนแปลงใด ๆ ที่ทำกับวัตถุโมดูลจะถูกสะท้อนทุกที่ ตัวอย่างเช่น:
ไฟล์: 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
config.x
ฉันสามารถกำจัดมันได้หรือไม่ ฉันมาด้วยx = lambda: config.x
แล้วฉันมีค่าใหม่x()
มา ด้วยเหตุผลบางอย่างการa = config.x
ไม่มีเคล็ดลับสำหรับฉัน
from config import x
แก้ปัญหานั้นได้ไหม?
Python ใช้ฮิวริสติกแบบง่ายในการตัดสินใจว่าควรโหลดขอบเขตใดจากตัวแปรระหว่างท้องถิ่นและทั่วโลก หากชื่อตัวแปรปรากฏขึ้นทางด้านซ้ายมือของการมอบหมาย แต่ไม่ได้ประกาศเป็นโกลบอลจะถือว่าเป็นชื่อโลคัล หากไม่ปรากฏที่ด้านซ้ายมือของการมอบหมายจะถือว่าเป็นทั่วโลก
>>> 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
>>>
มาดูกันว่า baz ซึ่งปรากฏทางด้านซ้ายของการมอบหมายfoo()
เป็นLOAD_FAST
ตัวแปรเดียว
for
ลูปและชื่อหลังจากas
ในwith
และexcept
คำสั่งก็ถูกผูกไว้ด้วย
as
ในexcept
ประโยคนี้ไม่ชัดเจนสำหรับฉัน แต่จะถูกลบอัตโนมัติเพื่อบันทึกหน่วยความจำ
as ...
เป้าหมายในตัวจัดการข้อยกเว้น
หากคุณต้องการอ้างถึงตัวแปรกลางในฟังก์ชั่นคุณสามารถใช้คำหลักทั่วโลกเพื่อประกาศตัวแปรที่เป็นสากล คุณไม่จำเป็นต้องใช้มันในทุกกรณี (ในฐานะคนที่อ้างสิทธิ์ไม่ถูกต้อง) - หากไม่พบชื่อที่อ้างอิงในนิพจน์ในขอบเขตหรือขอบเขตในฟังก์ชันที่ฟังก์ชันนี้ถูกกำหนดมันจะถูกค้นหาในระดับสากล ตัวแปร
อย่างไรก็ตามหากคุณกำหนดให้กับตัวแปรใหม่ที่ไม่ได้ประกาศเป็นโกลบอลในฟังก์ชั่นมันจะถูกประกาศโดยปริยายว่าเป็นโลคัลและสามารถบดบังตัวแปรโกลบอลที่มีอยู่ด้วยชื่อเดียวกัน
นอกจากนี้ตัวแปรทั่วโลกยังมีประโยชน์ตรงกันข้ามกับความกระตือรือร้นของ OOP บางคนที่อ้างว่าเป็นอย่างอื่น - โดยเฉพาะอย่างยิ่งสำหรับสคริปต์ขนาดเล็กที่ OOP มีทักษะมากเกินไป
ถ้าฉันสร้างตัวแปรส่วนกลางในฟังก์ชันหนึ่งฉันจะใช้ตัวแปรนั้นในอีกฟังก์ชันหนึ่งได้อย่างไร
เราสามารถสร้างโลกด้วยฟังก์ชั่นต่อไปนี้:
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!!!'
โปรดทราบว่า "global" ใน Python ไม่ใช่ global อย่างแท้จริง - เป็น global เพียงระดับโมดูล ดังนั้นมันจึงใช้ได้เฉพาะกับฟังก์ชั่นที่เขียนในโมดูลที่เป็นแบบโกลบอลเท่านั้น ฟังก์ชั่นจำโมดูลที่พวกเขาเขียนดังนั้นเมื่อพวกเขาถูกส่งออกไปยังโมดูลอื่น ๆ พวกเขายังคงดูในโมดูลที่พวกเขาถูกสร้างขึ้นเพื่อค้นหาตัวแปรทั่วโลก
หากคุณสร้างตัวแปรท้องถิ่นด้วยชื่อเดียวกันมันจะบดบังตัวแปรทั่วโลก:
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
)
นอกจากคำตอบที่มีอยู่แล้วและทำให้สับสนมากขึ้น:
ในหลามตัวแปรที่อ้างถึงเฉพาะภายในฟังก์ชั่นที่มี ทั่วโลกโดยปริยาย ถ้าตัวแปรมีการกำหนดค่าใหม่ได้ทุกที่ภายในร่างกายของฟังก์ชั่นก็ถือว่าเป็นท้องถิ่น หากตัวแปรได้รับการกำหนดค่าใหม่ภายในฟังก์ชั่นตัวแปรจะอยู่ในพื้นที่โดยปริยายและคุณต้องประกาศอย่างชัดเจนว่าเป็น 'ทั่วโลก'
แม้ว่าในตอนแรกจะค่อนข้างแปลกใจ แต่การพิจารณาสักครู่ก็อธิบายสิ่งนี้ ในอีกด้านหนึ่งการกำหนดให้ส่วนกลางสำหรับตัวแปรที่กำหนดให้แถบกับผลข้างเคียงที่ไม่ได้ตั้งใจ ในทางกลับกันหากจำเป็นต้องใช้ทั่วโลกสำหรับการอ้างอิงระดับโลกทั้งหมดคุณจะต้องใช้งานโกลบอลตลอดเวลา คุณจะต้องประกาศเป็นโกลบอลทุกการอ้างอิงถึงฟังก์ชั่นในตัวหรือส่วนประกอบของโมดูลที่นำเข้า ความยุ่งเหยิงนี้จะกำจัดประโยชน์ของการประกาศทั่วโลกสำหรับการระบุผลข้างเคียง
ที่มา: กฎสำหรับตัวแปรโลคอลและตัวแปรโกลบอลใน Python คืออะไร .
ด้วยการประมวลผลแบบขนานตัวแปรส่วนกลางอาจทำให้เกิดผลลัพธ์ที่ไม่คาดคิดหากคุณไม่เข้าใจว่าเกิดอะไรขึ้น นี่คือตัวอย่างของการใช้ตัวแปรโกลบอลภายในการประมวลผลหลายตัว เราสามารถเห็นได้อย่างชัดเจนว่าแต่ละกระบวนการทำงานกับสำเนาของตัวแปรเอง:
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]
สิ่งที่คุณพูดคือใช้วิธีเช่นนี้
globvar = 5
def f():
var = globvar
print(var)
f() # Prints 5
แต่วิธีที่ดีกว่าคือใช้ตัวแปรโกลบอลเช่นนี้
globavar = 5
def f():
global globvar
print(globvar)
f() #prints 5
ทั้งสองให้ผลลัพธ์เดียวกัน
ตามที่ปรากฎคำตอบนั้นง่ายเสมอ
นี่คือโมดูลตัวอย่างขนาดเล็กที่มีวิธีง่ายๆในการแสดงใน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()
รหัสง่าย ๆ นี้ใช้งานได้ดีและมันจะทำงาน ฉันหวังว่ามันจะช่วย
global_vars
และเริ่มต้นข้อมูลในinit_global_vars
ที่ถูกเรียกในสคริปต์เริ่มต้น จากนั้นฉันก็สร้างวิธีการเข้าถึงสำหรับแต่ละ var ทั่วโลกที่กำหนดไว้ ฉันหวังว่าฉันสามารถโหวตได้หลายครั้ง! ขอบคุณ Peter!
คุณจำเป็นต้องอ้างอิงตัวแปรส่วนกลางในทุกฟังก์ชั่นที่คุณต้องการใช้
ดังต่อไปนี้:
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]
"""
คุณไม่ได้เก็บโกลบอลไว้ในตัวแปรโลคอลเพียงแค่สร้างการอ้างอิงแบบโลคัลกับออบเจ็กต์เดียวกับที่การอ้างอิงแบบโกลบอลดั้งเดิมของคุณอ้างถึง จำไว้ว่าทุกอย่างในงูใหญ่นั้นเป็นชื่อที่อ้างถึงวัตถุและไม่มีอะไรถูกคัดลอกในการทำงานปกติ
หากคุณไม่จำเป็นต้องระบุอย่างชัดเจนว่าเมื่อใดที่ตัวระบุจะอ้างอิงไปยังส่วนกลางที่กำหนดไว้ล่วงหน้าคุณจะต้องระบุอย่างชัดเจนเมื่อตัวระบุเป็นตัวแปรท้องถิ่นใหม่แทน (ตัวอย่างเช่นคำสั่ง 'var' เห็นใน JavaScript) เนื่องจากตัวแปรท้องถิ่นนั้นพบได้ทั่วไปมากกว่าตัวแปรทั่วโลกในระบบที่จริงจังและไม่สำคัญระบบ Python จึงเหมาะสมกว่าในกรณีส่วนใหญ่
คุณอาจมีภาษาที่พยายามเดาโดยใช้ตัวแปรโกลบอลหากมีอยู่หรือสร้างตัวแปรโลคอลหากไม่มี อย่างไรก็ตามนั่นอาจเป็นข้อผิดพลาดได้ง่าย ตัวอย่างเช่นการอิมพอร์ตโมดูลอื่นอาจแนะนำตัวแปรโกลบอลโดยใช้ชื่อนั้นโดยไม่ได้ตั้งใจซึ่งเป็นการเปลี่ยนพฤติกรรมของโปรแกรมของคุณ
ลองสิ่งนี้:
def x1():
global x
x = 6
def x2():
global x
x = x+1
print x
x = 5
x1()
x2() # output --> 7
ในกรณีที่คุณมีตัวแปรท้องถิ่นที่มีชื่อเดียวกันคุณอาจต้องการที่จะใช้ฟังก์ชั่นglobals()
globals()['your_global_var'] = 42
ติดตามและเพิ่มส่วนต่อใช้ไฟล์เพื่อเก็บตัวแปรโกลบอลทั้งหมดที่ประกาศไว้แบบโลคัลแล้ว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):
import ... as ...
? ทำไมไม่เป็นเช่นนั้นimport ...
?
global
:-) => +1 :-) โปรดแก้ไขคำตอบของคุณเพื่อชี้แจงการซักถามเหล่านี้ที่คนอื่น ๆ อาจมี Cheers
การเขียนไปยังองค์ประกอบที่ชัดเจนของอาร์เรย์ทั่วโลกนั้นไม่จำเป็นต้องมีการประกาศทั่วโลกแม้ว่าการเขียนถึง "wholesale" จะมีความต้องการดังกล่าว:
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
ฉันกำลังเพิ่มสิ่งนี้เนื่องจากฉันไม่ได้เห็นคำตอบอื่นใดและอาจเป็นประโยชน์สำหรับบางคนที่ต้องดิ้นรนกับสิ่งที่คล้ายกัน globals()
ฟังก์ชันส่งกลับแน่นอนพจนานุกรมสัญลักษณ์ทั่วโลกที่คุณสามารถ "อย่างน่าอัศจรรย์" ข้อมูลให้พร้อมใช้งานสำหรับส่วนที่เหลือของรหัสของคุณ ตัวอย่างเช่น:
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
จะให้คุณถ่ายโอนข้อมูล / โหลดตัวแปรจากและเข้าสู่ namespace ส่วนกลาง สะดวกสบายมากไม่ต้องวุ่นวายไม่ต้องยุ่งยาก ค่อนข้างแน่ใจว่าเป็น Python 3 เท่านั้น
globals()
คืนค่า globals ที่มีในบริบทท้องถิ่นเสมอดังนั้นการกลายพันธุ์ที่นี่อาจไม่สะท้อนในโมดูลอื่น
อ้างอิงคลาสเนมสเปซที่คุณต้องการให้การเปลี่ยนแปลงแสดงขึ้น
ในตัวอย่างนี้นักวิ่งใช้ค่าสูงสุดจากไฟล์กำหนดค่า ฉันต้องการให้การทดสอบของฉันเปลี่ยนค่าของmaxเมื่อนักวิ่งใช้มัน
หลัก / config.py
max = 15000
หลัก / 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()
Globals ที่เกี่ยวข้องกับการประมวลผลหลายตัวบนแพลตฟอร์ม / envrionments ที่แตกต่างกันเช่น Windows / Mac OS ในด้านหนึ่งและ Linux ในอีกด้านหนึ่งมีปัญหา
ฉันจะแสดงให้คุณเห็นด้วยตัวอย่างง่ายๆที่ชี้ให้เห็นปัญหาที่ฉันพบเมื่อไม่นานมานี้
หากคุณต้องการที่จะเข้าใจว่าทำไมสิ่งต่าง ๆ บน Windows / MacOs และ Linux คุณจำเป็นต้องรู้ว่ากลไกเริ่มต้นในการเริ่มกระบวนการใหม่ใน ...
การเริ่มต้นการจัดสรรหน่วยความจำแตกต่างกันในการเริ่มต้น ... (แต่ฉันไม่ได้เข้าไปที่นี่)
ลองมาดูปัญหา / ตัวอย่าง ...
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)
หากคุณเรียกใช้งานบน Windows (และฉันคิดว่าบน MacOS ด้วย) คุณจะได้ผลลัพธ์ต่อไปนี้ ...
task 0: counter = 1
task 1: counter = 2
task 2: counter = 3
task 3: counter = 4
หากคุณใช้งานบน Linux คุณจะได้สิ่งต่อไปนี้แทน
task 0: counter = 1
task 1: counter = 1
task 2: counter = 1
task 3: counter = 1