Використання глобальних змінних у функції


3113

Як я можу створити або використовувати глобальну змінну у функції?

Якщо я створюю глобальну змінну в одній функції, як я можу використовувати цю глобальну змінну в іншій функції? Чи потрібно зберігати глобальну змінну в локальній змінній функції, яка потребує її доступу?

Відповіді:


4244

Ви можете використовувати глобальну змінну в інших функціях, оголосивши її як 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ключове слово.

Дивіться інші відповіді, якщо ви хочете поділитися глобальною змінною між модулями.


838
Крайне перебільшення називати глобалісти як "настільки небезпечними". Глобали ідеально чудові на будь-якій мові, яка коли-небудь існувала і коли-небудь існуватиме. Вони мають своє місце. Що ви повинні сказати, це те, що вони можуть спричинити проблеми, якщо у вас немає поняття, як програмувати.
Антоній

207
Я думаю, що вони досить небезпечні. Однак у python "глобальні" змінні насправді є рівнем модулів, що вирішує багато проблем.
Фабіо Сантос

246
Я не погоджуюся, що причина Python вимагає globalключового слова в тому, що глобальні поля небезпечні. Скоріше, це тому, що мова не вимагає від вас явного декларування змінних і автоматично передбачає, що змінна, яку ви призначаєте, має область функцій, якщо ви не скажете це інше. globalКлючове слово є засобом , яке надається сказати інакше.
Nate CK

7
@avgvstvs: І якщо ви реалізуєте ту саму програму без глобальних точок, у вас все одно буде однакова кількість кодових шляхів. Аргумент, який ви зробили, не проти глобалістів.
Гонки легкості по орбіті

13
@LightnessRacesinOrbit Я не розумію вашої точки зору. Якщо ви видалите глобальну змінну, ви видалите ускладнюючий фактор у тому, що зараз довільні функції більше не можуть змінювати стан програми в різних точках виконання - таким чином змінюючи виконання таким чином, що в іншому випадку непомітно для інших функцій, що покладаються на цю змінну. Вам більше не доведеться відслідковувати "Чи f2()змінився стан, щоб тепер f3()зробити щось несподіване? Тепер функції можуть діяти агностично до стану зовнішньої програми.
avgvstvs

775

Якщо я правильно розумію вашу ситуацію, ви бачите результат того, як 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 передбачає, що будь-яке ім'я, призначене будь-де в межах функції, є локальною для цієї функції, якщо прямо не сказано інше. Якщо воно читається лише з імені, а ім’я не існує локально, воно спробує знайти ім'я в будь-яких областях, що містять область (наприклад, глобальна область застосування модуля).

myGlobalОтже, призначаючи ім'я 42 , Python створює локальну змінну, яка затінює глобальну змінну того самого імені. Це місцеве виходить за межі та збирається сміття під час func1()повернення; тим часом, func2()ніколи не можна побачити нічого, крім (немодифікованого) глобального імені. Зауважте, що це рішення простору імен відбувається під час компіляції, а не під час виконання - якщо ви повинні прочитати значення myGlobalвнутрішньої частини func1()перед тим, як призначити його, ви отримаєте UnboundLocalError, оскільки Python вже вирішив, що він повинен бути локальною змінною, але це ще не мала з цим пов'язаного значення. Але використовуючи globalоператор ' ', ви кажете Python, що він повинен шукати інше ім'я, а не призначати його локально.

(Я вважаю, що така поведінка в основному виникла за рахунок оптимізації локальних просторів імен - без такої поведінки VM Python потрібно було б виконати щонайменше три пошукові імена щоразу, коли нове ім'я присвоюється всередині функції (для того, щоб ім'я не було ' t вже існує на рівні модуля / вбудованого), що значно сповільнить дуже поширену операцію.)


Ви згадали, що рішення простору імен відбувається під час компіляції , я не думаю, що це правда. з того, що я дізнаюся, компіляція python перевіряє лише синтаксичну помилку, а не помилку імені, спробуйте цей приклад def A (): x + = 1 , якщо ви не запустите його, він не дасть UnboundLocalError , будь ласка, перевірте дякую
watashiSHUN

1
Зазвичай велика літера використовується для глобальних змінних, таких якMyGlobal = 5
Василіс,

3
@watashiSHUN: Рішення імен це станеться під час компіляції. Визначення xмісцевого значення відрізняється від перевірки під час виконання, якщо локальне ім'я було прив'язане до значення до його першого використання.
BlackJack

9
@Vassilis: Поширена великі букви всіх букв: MY_GLOBAL = 5. Дивіться посібник зі стилів для Python Code .
BlackJack

223

Ви можете вивчити поняття просторів імен . У Python модуль є природним місцем для глобальних даних:

У кожного модуля є своя приватна таблиця символів, яка використовується як глобальна таблиця символів усіма функціями, визначеними в модулі. Таким чином, автор модуля може використовувати глобальні змінні в модулі, не турбуючись про випадкові зіткнення з глобальними змінними користувача. З іншого боку, якщо ви знаєте , що ви робите , ви можете торкнутися глобальних змінних модулем , з тими ж позначеннями , які використовуються для позначення своїх функцій modname.itemname.

Тут описано конкретне використання модуля global-in-a-a - Як я поділяю глобальні змінні між модулями? , а для повноти вміст поділився тут:

Канонічним способом обміну інформацією між модулями в межах однієї програми є створення спеціального модуля конфігурації (часто його називають 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

1
чомусь мені не подобається, чи config.x можу я її позбутися? Я прийшов, x = lambda: config.xі тоді я отримав нове значення x(). чомусь, що a = config.xне робить для мене хитрощів.
vladosaurus

3
@vladosaurus чи from config import xвирішує це?
jhylands

93

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змінною.


12
Евристичний вигляд обов'язкових операцій . Присвоєння - одна така операція, імпорт - інша. Але ціль forциклу та ім'я після asв withта exceptоператорах також зобов'язані.
Martijn Pieters

@MartijnPieters Ім’я після цього asв exceptпункті для мене це було не очевидно. Але це автоматично видаляється, щоб зберегти пам'ять.
Роберт

1
@Robert: не для економії пам’яті, а для уникнення створення кругової посилання, що може призвести до витоку пам’яті. Причиною цього є те, що виняток посилається на зворотний зворотний зворот, а у зворотному відстеженні посилається на все локальне та глобальне простір імен уздовж всього стека викликів, включаючи as ...ціль у обробнику винятків.
Martijn Pieters

62

Якщо ви хочете посилатися на глобальну змінну у функції, ви можете використовувати ключове слово global, щоб оголосити, які змінні є глобальними. Використовувати його не потрібно в усіх випадках (як хтось тут неправильно стверджує) - якщо ім'я, на яке посилається вираз, не може бути знайдено в локальному масштабі або області дії функцій, в яких визначена ця функція, вона шукається серед глобальних змінні.

Однак якщо ви призначите нову змінну, не оголошену як глобальну у функції, вона неявно оголошується локальною, і вона може затьмарити будь-яку існуючу глобальну змінну з тим самим іменем.

Також глобальні змінні корисні, всупереч деяким завзяттям OOP, які стверджують інакше - особливо для менших сценаріїв, де OOP є надмірним.


Абсолютно повторно. завзяття. Більшість користувачів Python використовують його для створення сценаріїв та створення невеликих функцій для розділення невеликих шматочків коду.
Пол Узак

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!!!'

Зауважте, що "глобальний" в Python не є справді глобальним - він лише глобальний на рівні модулів. Тож він доступний лише для функцій, записаних у модулях, у яких він глобальний. Функції запам'ятовують модуль, в який вони записані, тому, коли вони експортуються в інші модулі, вони все ще шукають модуль, в якому вони були створені, щоб знайти глобальні змінні.

Локальні змінні з тим же найменуванням

Якщо ви створите локальну змінну з тим самим іменем, вона затьмарить глобальну змінну:

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
@anonmanx Я не знаю, чому ти застряв, це та сама поведінка у методі, як у звичайній функції. Але я оновлю свою відповідь вашим зауваженням та деяким демо-кодом, добре?
Аарон Холл

1
@anonmanx як це?
Аарон Холл

добре, зрозумів. Тому мені доведеться явно викликати цю функцію для використання цієї глобальної змінної.
anonmanx

47

На додаток до вже існуючих відповідей і зробити це більш заплутаним:

У Python є змінні, на які посилається лише всередині функції неявно глобальні . Якщо змінній присвоєно нове значення в будь-якому місці в тілі функції, вона вважається локальною . Якщо змінній колись присвоюється нове значення всередині функції, змінна неявно локальна, і вам потрібно явно оголосити її як "глобальну".

Хоча спочатку трохи дивно, це пояснює момент. З одного боку, вимога глобального для призначених змінних забезпечує смугу проти непередбачуваних побічних ефектів. З іншого боку, якби глобальний був необхідний для всіх глобальних посилань, ви б використовували глобальний весь час. Вам доведеться оголосити як глобальну кожну посилання на вбудовану функцію або на компонент імпортного модуля. Ця сутичка загрожує корисності глобальної декларації для виявлення побічних ефектів.

Джерело: Які правила для локальних та глобальних змінних у Python? .


34

При паралельному виконанні глобальні змінні можуть спричинити несподівані результати, якщо ви не розумієте, що відбувається. Ось приклад використання глобальної змінної в рамках багатопроцесорної обробки. Ми чітко бачимо, що кожен процес працює з власною копією змінної:

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
дякую, я новачок у python, але знаю трохи Java. те, що ти сказав, працювало на мене. і писати глобальні а <ENTER> в класі .. здається, більше сенсу для мене , ніж в функції написання «глобальний» в .. Я помітив , що ви не можете сказати , глобальний а = 4
barlop

2
Це, мабуть, найпростіший, але дуже корисний для мене питон. Я називаю цей модуль global_varsі ініціалізую дані в init_global_vars, які викликаються в сценарії запуску. Потім я просто створюю метод accessor для кожного визначеного глобального 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
'у кожній функції, яку ви хочете використовувати', є невірною помилкою, має бути ближче до: 'у кожній функції, де ви хочете оновити '
spazm

21

Ви насправді не зберігаєте глобальний код у локальній змінній, просто створюєте локальну посилання на той самий об’єкт, на який посилається ваша первісна глобальна посилання. Пам'ятайте, що майже все в Python - це ім'я, що посилається на об'єкт, і нічого не копіюється при звичайній роботі.

Якщо вам не потрібно було чітко вказувати, коли ідентифікатор повинен посилатися на заздалегідь визначений глобальний, ви, мабуть, повинні явно вказати, коли ідентифікатор замість цього є новою локальною змінною (наприклад, з чимось на зразок команди 'var' видно в JavaScript). Оскільки локальні змінні більш поширені, ніж глобальні змінні в будь-якій серйозній і нетривіальній системі, система Python має більш сенс у більшості випадків.

Ви можете мати мову, яка намагалася відгадати, використовуючи глобальну змінну, якщо вона існує, або створивши локальну змінну, якщо вона не була. Однак це було б дуже схильним до помилок. Наприклад, імпорт іншого модуля може ненавмисно ввести глобальну змінну за цим іменем, змінивши поведінку вашої програми.




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()Функція повертає змінюваний словник глобальний символ , де ви можете «чарівно» дані зробити доступними для решти коду. Наприклад:

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

Просто дозволить вам скидати / завантажувати змінні з та в глобальний простір імен. Супер зручно, без мюс, без суєти. Досить впевнений, що це лише Python 3.


3
globals()завжди повертає глобальний доступний локальний контекст, тому мутація тут може не відображатися в іншому модулі.
Кіран Джонналагада

6

Посилайтеся на простір імен класів, де потрібно відобразити зміну.

У цьому прикладі бігун використовує max з конфігурації файлу. Я хочу, щоб мій тест змінив значення max, коли бігун використовує його.

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

Глобальні штрафи - за винятком багатопроцесорної обробки

Глобальні мережі, пов'язані з багатопроцесорною роботою на різних платформах / оточеннях, як Windows / Mac OS з одного боку, і Linux з іншого, викликають проблем.

Я покажу вам це на простому прикладі, вказуючи на проблему, з якою я стикався певний час тому.

Якщо ви хочете зрозуміти, чому в Windows / MacO та Linux все інакше, вам потрібно знати, що механізм за замовчуванням для запуску нового процесу на ...

  • Windows / MacO - це "нерест"
  • Linux - це "fork"

Вони відрізняються ініціалізацією розподілу пам’яті ... (але я тут не вдаваюся в це).

Давайте подивимось на проблему / приклад ...

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

Якщо ви запускаєте це в Windows (і, мабуть, і на MacOS), ви отримуєте наступний висновок ...

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

Linux

Якщо ви запустите це в Linux, ви отримаєте наступне.

task 0: counter = 1
task 1: counter = 1
task 2: counter = 1
task 3: counter = 1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.