Разница между определением функции внутри и снаружи другой функции [дубликат]

Возможно, не такой полезный ответ, но у меня была та же проблема при изменении порядка столбцов и ошибка, подобная той, что приведена в следующем примере. Имея много столбцов, я переупорядочил их и как-то вставил один после закрытия тега /DataGrid.Columns:

       <DataGridTemplateColumn x:Name="addedDateColumn" Header="Added Date" Width="SizeToHeader">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=AddedDate}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
            <DataGridTemplateColumn x:Name="rowguidColumn" Header="rowguid" Width="SizeToHeader">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=rowguid}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
    </DataGrid>

В любом случае, потеряно полчаса из-за этого. Надеюсь, это поможет другим.

2
задан eyllanesc 16 January 2019 в 15:42
поделиться

2 ответа

Я думаю, что это ваша глобальная сфера, которая загрязнена. Посмотрите на этот пример:

import sympy as sy

def f(x, w1, w2):
    return w1 * x**3 + w2 * x - 1

def derivative(w1, w2, pt):
    x = sy.Symbol('x')

    # Get derivative of f(x)
    def df(x, w1, w2):
        return sy.diff(f(x, w1, w2),x)

    # Evaluate at point x
    return df(x, w1, w2).subs(x,pt)

print(derivative(5, 8, 2))

Это просто измененная версия вашего примера 2, и он возвращает тот же ответ.

0
ответ дан Hans Daigle 16 January 2019 в 15:42
поделиться

Вложенная функция имеет доступ к локальным именам в родительской функции. Когда вы определяете f за пределами , он не может получить доступ к локальным w1 и w2, поэтому он должен будет предположить, что это глобалы .

И если вы не определили w1 и w2 на глобальном уровне, ваша вторая версия фактически поднимает NameError:

>>> import sympy as sy
>>> def f(x):
...     return w1 * x**3 + w2 * x - 1
...
>>> def derivative(w1, w2, pt):
...     x = sy.Symbol('x')
...     def df(x):
...         return sy.diff(f(x),x)
...     return df(x).subs(x,pt)
...
>>> derivative(5, 8, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in derivative
  File "<stdin>", line 4, in df
  File "<stdin>", line 2, in f
NameError: name 'w1' is not defined

То, что вы не получили средства исключения Вы уже уже определили w1 и w2 ранее, и именно эти значения используются для предоставления вашего неверного ответа.

Вы можете «исправить» свой второй пример, установив вместо него w1 и w2 как глобальные. На самом деле не имеет значения, что вы передаете в качестве первого и второго аргументов в вызов derivative(), потому что эти значения аргументов w1 и w2 полностью игнорируются :

>>> w1 = 5
>>> w2 = 8
>>> derivative('This value is ignored', 'And so is this one', 2)
68

В вашей локальной установке вы , вероятно, устанавливаете w1 и w2 в 4 и 5 соответственно, потому что это те значения, для которых x равно 53:

>>> w1 = 4
>>> w2 = 5
>>> derivative('This value is ignored', 'And so is this one', 2)
53

Для вашего первого примера, w1 и w2 предоставлены местными жителями в derivative(); Неважно, какие глобальные имена вы определили, они не будут использоваться вместо этого.

Если вы хотите определить f за пределами derivative() и по-прежнему передавать сначала w1 и w2 в derivative(), то вам также необходимо передать те же значения в функцию f() :

def f(x, w1, w2):
    return w1 * x**3 + w2 * x - 1

def derivative(w1, w2, pt):
    x = sy.Symbol('x')

    # Get derivative of f(x, w1, w2)
    def df(x):
        return sy.diff(f(x, w1, w2), x)

    # Evaluate at point x
    return df(x).subs(x,pt)

Теперь f() явно получает w1 и w2 из вложенной функции df(), а не из глобальных.

0
ответ дан Martijn Pieters 16 January 2019 в 15:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: