【问题标题】:How to make Python function return static variable?如何让 Python 函数返回静态变量?
【发布时间】:2017-09-18 01:30:59
【问题描述】:

我正在尝试构建一个WTForms custom validator 来检查重复的图像哈希。为此,我在表单验证器中使用了嵌套函数。问题是当我在外部函数中设置一个变量(内部函数的结果)时,对外部变量的任何后续引用都会再次调用内部函数。

例如:

def dupe_check(self, field):
    def get_hash():
        f = field.data
        img = Image.open(f)
        imghash = imagehash.dhash(img)
        f.seek(0)
        return imghash
    imghash = get_hash()
    hashcheck = Sights.query.filter(Sights.image_hash == imghash).first()
    if hashcheck == imghash:
        print('dupe')
        raise ValidationError('duplicate hash!')
    else:
        print('no dupe') 

如果在数据库中没有哈希的情况下运行,我会打印no dupe 并上传图像。

但是,如果哈希值存在于数据库中,当执行到达if hashcheck == imghash: 时,我会崩溃,因为imghash 似乎再次调用get_hash(),而不是简单地返回先前使用imghash = get_hash() 设置的哈希字符串。

您可以在下面看到imagehash 程序被调用(并崩溃)而不是简单的哈希字符串。

127.0.0.1 - - [17/Sep/2017 17:49:36] "POST /add HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/flask/_compat.py", line 33, in reraise
    raise value
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/mrrg/dev/flaskimg/project/sights/views.py", line 74, in add_image
    if form.validate_on_submit():
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/flask_wtf/form.py", line 101, in validate_on_submit
    return self.is_submitted() and self.validate()
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/wtforms/form.py", line 310, in validate
    return super(Form, self).validate(extra)
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/wtforms/form.py", line 152, in validate
    if not field.validate(self, extra):
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/wtforms/fields/core.py", line 204, in validate
    stop_validation = self._run_validation_chain(form, chain)
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/wtforms/fields/core.py", line 224, in _run_validation_chain
    validator(form, self)
  File "/home/mrrg/dev/flaskimg/project/sights/forms.py", line 71, in dupe_check
    if hashcheck == imghash:
  File "/home/mrrg/dev/flaskimg/venv/lib/python3.5/site-packages/imagehash/__init__.py", line 85, in __eq__
    return numpy.array_equal(self.hash.flatten(), other.hash.flatten())
AttributeError: 'Sights' object has no attribute 'hash'

我以为imghash = get_hash() 会设置从内部函数返回的变量的新实例?如何设置要操作的静态变量,并避免额外调用内部函数?

我还尝试在内部函数的imghash 上设置全局/非本地,结果相同。

【问题讨论】:

    标签: python python-3.x flask wtforms


    【解决方案1】:

    据我了解,您的代码尝试将 Sight 对象与 ImageHash 对象进行比较,但 Sight 类代码实现仅在 2 个 Sight 对象之间进行比较,因此出现错误

    【讨论】:

    • 我不确定我是否关注你。我不是在 Sight 课程中进行比较。我定义了 2 个变量:imghash 是从内部函数创建的,hashcheck 是从 SQLAlchemy 查询创建的。
    • 你能告诉我变量 hashcheck 和 imghash 的类型吗?
    • 啊,我明白了,我有两种不同的变量类型:<class 'imagehash.ImageHash'><class 'project.models.Sights'>。标准化变量以进行比较的最佳方法是什么?
    • 对于哈希值,我认为将对象类型转换为字符串进行比较是合适的
    • 这最终奏效了。感谢@Tung-vs 的帮助。
    猜你喜欢
    • 2015-08-17
    • 2011-11-12
    • 1970-01-01
    • 2014-07-30
    • 2013-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-18
    相关资源
    最近更新 更多