• Members 2 сообщения
    1 августа 2021 г. 8:08

    Добрый день! Вопрос знатокам питона, сам уже всю голову сломал:

    class A:
    
        @staticmethod
        def func(value, value1):
    
            class B:
    
                class C:
    
                    value = value
                    value1 = value1
    
            return B
    
    
    b = A.func('value', 'value1')
    print(b.C.value)  
    print(b.C.value1)
    
    Traceback (most recent call last):
      File "d:\code\python\prosto\prosto.py", line 15, in <module>
        b = A.func('value', 'value1')
      File "d:\code\python\prosto\prosto.py", line 5, in func
        class B:
      File "d:\code\python\prosto\prosto.py", line 7, in B
        class C:
      File "d:\code\python\prosto\prosto.py", line 9, in C
        value = value
    NameError: name 'value' is not defined
    

    Но, если мы поменяем именование аргументов функции func или атрибутов класса C, то

    class A:
    
        @staticmethod
        def func(some_value, some_value1):
    
            class B:
    
                class C:
    
                    value = some_value
                    value1 = some_value1
    
            return B
    
    
    b = A.func('somevalue', 'somevalue1')
    print(b.C.value)  # somevalue
    print(b.C.value1)  # somevalue1
    

    Вопрос: из-за чего так происходит?

  • Team
    1 августа 2021 г. 9:28

    Вы же перезатираете value и потом подставляете уже какой-то другой value, про который Python ничего не знает.

  • Members 2 сообщения
    1 августа 2021 г. 10:48

    А, да! В атрибуте класса C хранится не объект, а ссылка на объект, который мы успешно перезатерли.
    На данном примере в этом легко убедиться:

    l = [1, 2]
    
    def func():
    
        class A:
    
            value = l
    
            @classmethod
            def update_value(cls):
                cls.value.append(3)
    
        return A
    
    a = func()
    print(a.value)  # [1, 2]
    print(l)  # [1, 2]
    a.update_value()
    print(a.value)  # [1, 2, 3]
    print(l)  # [1, 2, 3] (т.е также изменился)