Как поменять словарь вне фукшиона, если я переопределю его внутри? - PullRequest
0 голосов
/ 27 апреля 2019

Я использую Python 3.6 У меня есть код с множеством уровней функций. Во всех них я использую один словарь, представленный в качестве аргумента. Так что, если я где-то меняю это, оно меняется везде вниз по уровням. Но в одной функции мне нужно заменить ее на другую, и там возникла проблема: переопределить словарь внутри, сломать ссылку на основной текст и не изменить его на уровни. Кроме того, я не могу использовать return, поскольку он переопределит словарь, всего на один уровень вниз.

Итак:

Test = {"1":"2"}

def Teser(Test):
    Test["Hell"]= "No"

Teser(Test)
print(Test)

это выводит:

{'1': '2', 'Hell': 'No'}

Но

Test = {"1":"2"}

def Teser(Test):
    Test = {"Hell":"No"}

Teser(Test)
print(Test)

otputs (с и без возврата):

{'1': '2'}

Есть ли способ сделать результат второго кода таким же, как первый, без возврата или глобальных значений?

Ответы [ 6 ]

2 голосов
/ 27 апреля 2019

Вы переназначаете параметр, а не глобальную переменную, что в любом случае является плохой практикой

Это эквивалентно этому, и ожидание Test изменения

Test = {"1":"2"}
def Teser(t):
    t = {"Hell":"No"}
Teser(Test)

Даже если бы это сработало, вы потеряли бы ключ "1", который, я не уверен, является частью проблемы ...

В любом случае, здесь рекомендуется использовать глобальное имя и другое имя параметра

Test = {"1":"2"}
def Teser(t):
    # you can still reference t values, if needed 
    global Test  # while not necessary, it clarifies which variable scope is used 
    Test = {"Hell":"No"}
Teser(Test)
print(Test)

И обратите внимание: только классы должны быть написаны заглавными буквами, а не переменные и функции

1 голос
/ 27 апреля 2019

Вы можете попробовать это:

Test = {"1":"2"}

def Teser(Test):
    Test.update({"Hell":"No"} , last = True)

Teser(Test)

Это добавит ключ "Ад" в начале вашего словаря.

0 голосов
/ 27 апреля 2019

Если я правильно понимаю ваши требования, вам нужно использовать локальный dict с тем же именем, и после того, как работа будет завершена, каким-то образом обновите глобальное значение, прежде чем вызывать что-то еще.

Test = {"1":"2"}

def update_global(local_dict):
    global Test
    Test.update(local_dict)
    return Test

def Teser(Test):
    Test = {"Hell":"No"}
    #do work
    Test_local = Test.copy() #incase you still need to access the local variables for some reason
    Test = update_global(Test)
    #do some other work. If you need the local test back, just reassign.

Teser(Test)
print(Test)
#{'1': '2', 'Hell': 'No'}

Этот код может нуждаться в рефакторинге, хотя имена не должны быть так тесно связаны внутри функций, если вы можете помочь ему.

0 голосов
/ 27 апреля 2019

Просто сделайте метод x.update на вашем файле, например:

def Teser(Test):
    Test.update({'Hell':'No'})
0 голосов
/ 27 апреля 2019

Если вы хотите изменить глобальную переменную, вам не нужно передавать ее в качестве параметра.Если вы передадите его, метод создаст локальную переменную с именем «Test» и только модифицирует ее.Даже если вы не передадите его как параметр, он создаст локальную переменную.Чтобы использовать глобальную переменную, напишите global variable_name в начале вашего метода.

Test = {"1":"2"}

def Teser():
    global Test
    Test = {"Hell":"No"}

Teser()
print(Test)
0 голосов
/ 27 апреля 2019

Есть ли способ сделать результат второго кода таким же, как первый, без возврата или глобальных значений?

В большинстве случаев вам, вероятно, следует использовать return. Однако, если функции очень вложенные, может быть легко смоделировать глобальные переменные, используя висячие классы:

class SomeClass:
    def __init__(self):
        SomeClass.test = {"1": "2"}

    @classmethod
    def teser(cls, test):
        cls.test["Hell"]= "No"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...