Flask问题:TypeError:object.__new__()接受一个参数(要实例化的类型)

huangapple go评论54阅读模式
英文:

Flask problem TypeError: object.__new__() takes exactly one argument (the type to instantiate)

问题

问题:

cls._instance = super(MateDealer, cls).__new__(cls, *args, **kwargs)
sc = SessionController(db, User, Product, Vend)

更改为 Python 2:

cls._instance = super(MateDealer, cls).__new__(cls, *args, **kwargs)

我删除了它,并更改为 Python 3:

cls._instance = super().__new__(cls)

我尝试了但不起作用。

我尝试了所有的谷歌和堆栈溢出错误,但是我无法使它工作,如果你能帮助我,我将不胜感激。

英文:

I can't solve the error I get, I would be glad if you help me

problem :


cls._instance = super(MateDealer, cls).__new__(cls, *args, **kwargs)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sc = SessionController(db, User, Product, Vend)

import sys
import os
import re
from datetime import datetime, timedelta
import time
from flask_serial import Serial
from threading import Thread

class SessionController:

    def __init__(self, db, user, product, vend):
        self.db = db
        self.timer = None
        self._lock = False
        self.product = product
        self.vend = vend
        self.user = user
        self.active_user = ""
        self.md = MateDealer(self)
        self.md.start()
        self.user_id = None

    def is_locked(self):
        return self._lock

    def vend_start(self, user_id):
        self.user_id = user_id
        self.lock()
        user = self.user.query.get(self.user_id)
        self.active_user = user.name 
        self.md.start_session(user.balance)

    def vend_request(self, item):
        product = self.product.query.filter_by(slot=item).first()
        print (product)
        user = self.user.query.get(self.user_id)
        print (user)
        if user.balance >= product.price:
            self.md.approve_vend(product.price)
        else:
            self.md.deny_vend()

    def vend_success(self, item):
        product = self.product.query.filter_by(slot=item).first()
        product.stock -= 1
        user = self.user.query.get(self.user_id)
        user.balance -= product.price
        vend = self.vend(user.name, product.name, product.price, datetime.now())
        self.db.session.add(vend)
        self.db.session.commit()
        self.cancel()

    def lock(self):
        self._lock = True

    def unlock(self):
        self._lock = False

    def cancel(self):
        if self.timer != None:
            self.timer.stop()
            self.timer = None
        self.active_user = ""
        self.unlock()
        self.md.cancel_session()


class Timer(Thread):

    def __init__(self, time, callback):
        Thread.__init__(self)
        self.time = time
        self.callback = callback
        self.canceled = False

    def run(self):
        while self.time > 0 and not self.canceled:
            time.sleep(1)
            self.time -= 1

        if not self.canceled:
            self.callback()

    def stop(self):
        self.canceled = True


class MateDealer(Thread):
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(MateDealer, cls).__new__(cls, *args, **kwargs)
        return cls._instance

    def __init__(self, sc, *args, **kwargs):
        Thread.__init__(self)
        self.sc = sc
        self.serial = Serial()
        self.serial.port = '/dev/ttyACM0'
        self.serial.baudrate = 38400
        self.serial.bytesize = 8
        self.serial.parity = 'N'
        self.serial.stopbits = 1
        self.serial.timeout = 0.1
        self.running = False

    def run(self):
        try:
            self.serial.open()
        except Exception as e:
            print >> sys.stderr, e.message
            return

        print (self.serial)
        self.running = True
        msg = ''
        while self.running:
            byte = self.serial.read()
            if byte != '':
                msg += byte
            if msg.endswith('\n'):
                self.parse_cmd(msg)
                msg = ''

        if self.serial.is_open():
            self.serial.close()

    def start_session(self, balance):
        self.serial.write('start-session %d\r\n' % balance)
        print ('start-session %d' % balance)

    def approve_vend(self, price):
        self.serial.write('approve-vend %d\r\n' % price)
        print ('approve-vend %d\r\n' % price)

    def deny_vend(self):
        self.serial.write('deny-vend\r\n')
        print ('deny-vend')

    def cancel_session(self):
        self.serial.write('cancel-session\r\n')
        print ('cancel-session')

    def parse_cmd(self, cmd):
        cmd = cmd.strip()
        if cmd.startswith('vend-request'):
            _cmd, price, item = cmd.split(' ')
            self.sc.vend_request(item)
        elif cmd.startswith('vend-success'):
            _cmd, item = cmd.split(' ')
            self.sc.vend_success(item)
        elif cmd.startswith('session-complete'):
            self.sc.cancel()
        else:
            print (cmd)

changing with python 2

         cls._instance = super(MateDealer, cls).__new__(cls, *args, **kwargs)

i deleted it and for python3

         cls._instance = super().__new__()

i tried but it doesn't work

I tried all google and stack overflow errors, but I couldn't get it to work, I would appreciate it if you could help.

答案1

得分: 0

In Python 3,你需要不传递任何额外的参数给__new__调用,所以你需要:

cls._instance = super().__new__(cls)

尽管要注意的是,你实现的一个潜在问题是,每次调用MateDealer()时都会再次运行__init__... 这不是你想要的,我猜测你似乎试图创建一种单例。你在这里到底是要做什么?如果你只想要一个"singleton",那就不要费那么多劲。只需定义一个工厂函数来缓存实例和一个"private"类,所以快速而简单:

class _MateDealer(Thread):
    def __init__(self, sc, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.sc = sc
        self.serial = Serial()
        self.serial.port = '/dev/ttyACM0'
        self.serial.baudrate = 38400
        self.serial.bytesize = 8
        self.serial.parity = 'N'
        self.serial.stopbits = 1
        self.serial.timeout = 0.1
        self.running = False

__instance = None

def MateDealer(sc, *args, **kwargs):
    global __instance
    if __instance is None:
        __instance = _MateDealer(sc, *args, **kwargs)
    return __instance
英文:

In Python 3, you need to not pass any additional arguments to the __new__ call, so you need:

cls._instance = super().__new__(cls)

Although note, a potential problem with your implementation is that

 __init__

will be run again each time you call MateDealer()... which is not what you want, I surmise, from the fact that you seem to be trying to create some sort of singleton. What exactly is the purpose of what you are doing here?

If you just want a "singleton" don't even bother with all of this. Just define a factory function that caches the instance and a "private" class, so quick-and-dirty:

class _MateDealer(Thread):
    def __init__(self, sc, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.sc = sc
        self.serial = Serial()
        self.serial.port = '/dev/ttyACM0'
        self.serial.baudrate = 38400
        self.serial.bytesize = 8
        self.serial.parity = 'N'
        self.serial.stopbits = 1
        self.serial.timeout = 0.1
        self.running = False

__instance = None

def MateDealer(sc, *args, **kwargs):
    global __instance
    if __instance is None:
        __instance = _MateDealer(sc, *args, **kwargs)
    return _mate_instance

huangapple
  • 本文由 发表于 2023年6月6日 07:15:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76410538.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定