【问题标题】:How to declare a integer outside of a function [duplicate]如何在函数之外声明一个整数[重复]
【发布时间】:2019-10-26 17:41:27
【问题描述】:

我正在尝试使用 HTTP 发布请求将数据添加到我的 mysql 数据库,但是按照现在的设置方式,如果我们多次发布,则第一个帖子中的数据将更改为 0,因为我声明了所有同一个定义中的变量。我该如何解决这个问题?

我试图在第二个 def 中声明一个全局变量,但它只是循环那个 def 而不是我现在的那个。

#!/usr/bin/env python

import pymysql.cursors
from flask import Flask, request
from Crypto.Cipher import AES

connection = pymysql.connect('localhost','esp', 'password', 'points')
app = Flask(__name__)

@app.route('/post', methods = ["POST"])


def post():

    hits1 = 0
    hits2 = 0
    punch1 = 0
    punch2 = 0
    kick1 = 0
    kick2 = 0
    takedown1 = 0
    takedown2 = 0

    print(request.data)
    cipher = AES.new("abcdefghijklmnop")

    decryptedData = cipher.decrypt(request.data)


    data = decryptedData.decode("utf-8")
    print(data)

    print(data)
    if(data[:1]=="e"):
        if(data[1:2] == "1"):
            hits1+=1
            print(hits1)

    if (data[:1]=="1"):
        if(data[1:2]=="1"):
            punch1+=1
        elif(data[1:2]=="2"):
            kick1+=1
        elif(data[1:2]=="3"):
            takedown1+=1
    elif(data[:1]=="2"):
        if(data[1:2]=="1"):
            punch2+=1
        elif(data[1:2]=="2"):
            kick2+=1
        elif(data[1:2]=="3"):
            takedown2+=1
    points1 = punch1 + kick1 * 2 + takedown1 * 3
    points2 = punch2 + kick2 * 2 + takedown2 * 3
    print(points1)
    print(points2)

    try:
       with connection.cursor() as cursor:


            cursor.execute("INSERT INTO points values({0}, {1}, {2}, {3}, {4}, {5})".format(1, hits1, kick1, punch1, takedown1, points1))
            cursor.execute ("INSERT INTO points values({0}, {1}, {2}, {3}, {4}, {5})".format(2, hits2, kick2, punch2, takedown2, points2))


            connection.commit()
            print ("Data committed")
            return 'ok'
    except:
       connection.close()
app.run(host='0.0.0.0', port= 8090)

上一篇文章的值被更改为 0,但我想保留该值

【问题讨论】:

  • 我不清楚你想保留什么价值。

标签: python mysql python-3.x http flask


【解决方案1】:

您似乎希望将定义的变量保留在函数的顶部(hits1hits2...)。正如您所说,问题在于每次调用您的函数时都会重新定义这些变量。

最简单的方法(尽管设计有问题)是使用全局变量。要定义一个全局变量,你可以这样做:

hits1 = 0
hits2 = 0
# ...

@app.route('/post', methods = ["POST"])
def post():
    global hits1, hits2

    # ...

这样,值将在请求之间保留。我(个人)喜欢的一种方式,虽然它仍然是相同的想法,是将您的数据保存在“存储”类中:

class Storage:
    hits1 = 0
    hits2 = 0
    # ...

@app.route('/post', methods = ["POST"])
def post():
    # Instead of just using hits1, hits2, ...
    # We now use Storage.hits1, ...
    # Example:

    # ...

    Storage.points1 = Storage.punch1 + Storage.kick1 * 2 + Storage.takedown1 * 3

    # ...

这行得通。但是,当然,每次重新启动 Flask 应用程序时都会忘记这一点。如果您想要实际的持久性(这是您正在尝试实现的,因为您正在使用数据库),那么每次用户都会查询数据库(可能使用缓存以限制查询数量)向您的服务器发出请求:

class Database:
    def __init__(self):
        # Connect to your database
        self._hits1 = None

    @property
    def hits1(self):
        if self._hits1 is None:
            # self._hits1 = (Load data from the database)

        return self._hits1

    # ...

database = Database()

@app.route('/post', methods = ["POST"])
def post():
    # Loads from the database
    hits1 = database.hits1

    # ...

    # In this case, you'd probably want to move your INSERT query to your database class

一些 cmets:如果您想在请求之间保留您的值,可能您希望 UPDATE 您的数据库而不是 INSERTing 数据(但这只是我对您的解释代码)。

另外,使用an_sql_request.format(data) 是一种非常糟糕的做法,因为它可以帮助潜在的 SQL 注入。大多数数据库驱动程序都提供了一种准备查询的方法。例如mysql.connector:

cur = connection.cursor()
sql = "INSERT INTO MyTable (Col1, Col2) VALUES (%s, %s)"
cur.execute(sql, (value_for_col1, value_for_col2))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多