RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1394057
Accepted
Alex Kazantsev
Alex Kazantsev
Asked:2022-08-27 13:40:35 +0000 UTC2022-08-27 13:40:35 +0000 UTC 2022-08-27 13:40:35 +0000 UTC

如何在 Python 的装饰器中定义另一个函数的计数器?

  • 772

我使用二分法实现了用一个变量找到方程的根。那里的本质是:段被分成两半几次。如果段中间的函数为零或小于指定的错误,则找到根。否则,我们继续划分,然后将其左、右“边界”作为段的边界。

我将结果的输出组织在一个包装函数中,这样这个输出功能就不会影响主任务执行时间的计算——寻找根。

除其他事项外,还需要指示迭代次数(段被分成两半的次数)。正如我现在所做的(我自己也明白出了什么问题),它不起作用。错误:

NameError:名称“计数器”未定义

怎样成为?编码:

import numpy as np

def print_dichotomy(dichotomy):
    def wrapper(a,b,n, eps):
        print('Корни по методу дихотомии находятся в точках:')
        print(', '.join(map(lambda x: f'{x:.4f}', res)))
        print('Количество итераций: ', counter)   # ЗДЕСЬ ОШИБКА
    return wrapper

def f(x):
    return 1.2-np.log(x)-4*np.cos(2*x)

@print_dichotomy
def dichotomy (a,b,n, eps): # отрезок от a до b делим на n частей, погрешность eps
    """
    Функция отделения и уточнения корня
    """
    assert a!=0,  'a равно 0'
    assert b!=0, 'b равно 0'
    
    # сначала отделим корни
    grid=np.linspace(a, b, n)
    
    # далее уточним корни
    counter=0
    for x,y in zip(grid, grid[1:]):
        if f(x) * f(y) > 0: # если на отрезке нет корня, смотрим следующий
            continue
        root = None
        while ( abs(f(y)-f(x)) )>eps:     # пока отрезок больше заданной погрешности, выполняем нижестоящие операции:
            mid = (y+x)/2                   # получаем середину отрезка
            if f(mid) == 0 or f(mid)<eps:    # если функция в середине отрезка равну нулю или меньше погрешности:
                root = mid                  # корень равен серединному значению
                counter+=1
                break
            elif (f(mid) * f(x)) < 0:       # иначе если произведение функции в середине отрезка на функцию в т. а <0
                y = mid                     # серединой становится точка b
            else:
                x = mid                     #в другом случае - точка а
        if root:
            yield root
python
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    Denis Vlasenko
    2022-08-29T13:01:51Z2022-08-29T13:01:51Z

    您收到错误,因为 counter 是二分法函数的局部变量。它只存在于这个函数的范围内。在这个函数之外,这个变量是不可见的。

    并且由于二分法函数没有返回计数器变量的值作为其工作的结果,无论如何,在函数结束时,计数器变量不再存在。

    因此,您需要重新定义 counter ,使其不在本地范围内,而是在全局范围内。为此,您可以在二分法函数中使用全局语句。这不是最漂亮的解决方案,但它会解决您的问题。因此,counter变成了一个全局变量,我们在调用二分法函数之前对其进行了初始化。现在我们可以在执行二分法函数后使用计数器变量的值。

    我想提请注意的第二点是,我没有看到您调用传递给它的函数的包装函数内部。因此,出现另一个错误,即未定义 res 变量。相反,您只需调用 print_dichotomy 函数的参数中收到的原始函数。

    由于上述原因,代码可能如下所示:

    import numpy as np
    
    
    def print_dichotomy(func):
        def wrapper(*args, **kwargs):
            print('Корни по методу дихотомии находятся в точках:')
            print(', '.join(map(lambda x: f'{x:.4f}', func(*args, **kwargs))))
            print('Количество итераций: ', counter)
    
        return wrapper
    
    
    def f(x):
        return 1.2 - np.log(x) - 4 * np.cos(2 * x)
    
    
    @print_dichotomy
    def dichotomy(a, b, n, eps):  # отрезок от a до b делим на n частей, погрешность eps
        """
        Функция отделения и уточнения корня
        """
        global counter
        assert a != 0, 'a равно 0'
        assert b != 0, 'b равно 0'
    
        # сначала отделим корни
        grid = np.linspace(a, b, n)
    
        # далее уточним корни
        for x, y in zip(grid, grid[1:]):
            if f(x) * f(y) > 0:  # если на отрезке нет корня, смотрим следующий
                continue
            root = None
            while (abs(f(y) - f(x))) > eps:  # пока отрезок больше заданной погрешности, выполняем нижестоящие операции:
                mid = (y + x) / 2  # получаем середину отрезка
                if f(mid) == 0 or f(mid) < eps:  # если функция в середине отрезка равну нулю или меньше погрешности:
                    root = mid  # корень равен серединному значению
                    counter += 1
                    break
                elif (f(mid) * f(x)) < 0:  # иначе если произведение функции в середине отрезка на функцию в т. а <0
                    y = mid  # серединой становится точка b
                else:
                    x = mid  # в другом случае - точка а
            if root:
                yield root
    
    
    counter = 0
    dichotomy(1, 11, 15, 0.01)
    
    • 3

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5