类方法在Python中不返回值

2024-10-01 22:41:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我在将变量传递到函数并让它返回所需值时遇到了一些问题。为清楚起见,我将从PostgreSQL表中获取一条记录作为元组,然后将该元组的相关索引传递给类变量。除此之外,其他一切似乎都起作用了,我不知道为什么

代码如下:

from datetime import date
from decimal import Decimal
from config import config
import psycopg2


conn = None
try:
    params = config()
    conn = psycopg2.connect(**params)
    cur = conn.cursor()
    cur.execute('SELECT * FROM testdb.vitals ORDER BY "vitalsID"')

except (Exception, psycopg2.DatabaseError) as error:
    print(error)

row = cur.fetchone()


class Vitals:

    birth = date(1990, 12, 12)
    today = date.today()
    years = today.year - birth.year
    age = today.year - birth.year - ((today.month, today.day) < (birth.month, birth.day))
    weight = row[2]
    height = row[3]
    activity = row[4]
    goal = row[5]
    fatRatio = row[6]
    carbohydrateRatio = row[7]
    proteinRatio = row[8]

    def __init__(self):
        # connect and initialise vitals
        pass

    # display on gui

    @classmethod
    def activityText(cls):
        if cls.activity == Decimal(1.20):
            return testActivity * 2

    @classmethod
    def bmr(cls):
        return (Decimal(10) * cls.weight) + (Decimal(6.25) * cls.height) - (Decimal(5) * cls.age) + Decimal(5)

    @classmethod
    def tdee(cls):
        return Decimal(outputBmr * cls.activity)

    @classmethod
    def net(cls):
        if cls.goal == 1:
            return outputTdee - (outputTdee * Decimal(0.1))
        else:
            return outputTdee


importVitals = Vitals

testActivity = importVitals.activity
print(testActivity)

testActivityfunc = importVitals.activityText()
print(testActivityfunc)

outputBmr = round(importVitals.bmr())
print(outputBmr)

outputTdee = round(importVitals.tdee())
print(round(outputTdee))

outputNet = round(importVitals.net())
print(outputNet)

if importVitals.activity == Decimal(1.20):
    print('Hello')
else:
    print("\n")
    print(importVitals.activity)
    print(type(importVitals.activity))

关键类方法如下所示:

    @classmethod
    def activityText(cls):
        if cls.activity == Decimal(1.20):
            return testActivity * 2

输出(模块中的最终if语句更改后)如下所示:

1.20
<class 'decimal.Decimal'>
None
1751
2101
1891


1.20
<class 'decimal.Decimal'>

Process finished with exit code 0

为了便于阅读,以下是打印语句:


testActivity = importVitals.activity
print(testActivity)
print(type(importVitals.activity))

testActivityfunc = importVitals.activityText()
print(testActivityfunc)

outputBmr = round(importVitals.bmr())
print(outputBmr)

outputTdee = round(importVitals.tdee())
print(round(outputTdee))

outputNet = round(importVitals.net())
print(outputNet)

if importVitals.activity == Decimal(1.20):
    print('Hello')
else:
    print("\n")
    print(importVitals.activity)
    print(type(importVitals.activity))

所讨论的类方法总是返回None。还要注意模块末尾的if语句。它总是运行else分支,至少对我来说,它奇怪地打印1.20<class 'decimal.Decimal'>。因此,如果Python识别出importVitals.activity的实例类变量具有1.20值和<class 'decimal.Decimal'>的变量类型,那么为什么if语句或类方法没有返回我想要的结果呢?我有什么地方做错了吗

只是重申一下,所有其他方法和打印语句都按预期工作,因此我对此感到非常困惑

感谢所有花时间阅读本文的人。如果您能提供任何帮助,我将不胜感激


Tags: todayreturnifdefactivityclassrowcls
2条回答

看起来您有数字错误:

>>> Decimal(1.20)
Decimal('1.1999999999999999555910790149937383830547332763671875')
>>> Decimal("1.20")
Decimal('1.20')

使用字符串作为小数的输入,一切都应该正常。浮点数适用于快速计算,但不适用于精度

下面是一种更面向对象的方法来实现上述代码:

import sys
import psycopg2

from datetime import date
from decimal import Decimal
from config import config

class Vitals:
    def __init__(self, row):
        self.birth    = date(1990, 12, 12)
        self.today    = date.today()
        self.years    = today.year - birth.year
        self.age      = today.year - birth.year - ((today.month, today.day) < (birth.month, birth.day))
        self.weight   = row[2]
        self.height   = row[3]
        self.activity = Decimal(float(row[4]))
        self.goal     = row[5]
        self.fatRatio = row[6]
        self.carbohydrateRatio = row[7]
        self.proteinRatio = row[8]

    def activityText(self):
        if self.activity == Decimal(1.20):
            return self.activity * 2
        
    def bmr(self):
        return (Decimal(10)   * self.weight) +
               (Decimal(6.25) * self.height) -
               (Decimal(5)    * self.age)    +
                Decimal(5)

    def tdee(self):
        return Decimal(self.bmr() * self.activity)

    def net(self):
        if self.goal == 1:
            return self.tdee() - (self.tdee() * Decimal(0.1))
        else:
            return self.tdee()

def getDataFromDatabase(sql):
    conn = None
    try:
        params = config()
        conn   = psycopg2.connect(**params)
        cur    = conn.cursor()
        cur.execute(sql)
    except (Exception, psycopg2.DatabaseError) as error:
        print(error)
        return None
    return cur.fetchone()

def main():
    sql = 'SELECT * FROM testdb.vitals ORDER BY "vitalsID"'
    row = getDataFromDatabase(sql)
    vitals = Vitals(row)
    #Here you can do your stuff with vitals
    
main()

可以创建更多对象,并使用不同的值填充它们。我建议将构造函数中的row的值强制转换为适当的类型,如activity转换为十进制。
我不能保证这个版本会解决你最初的问题,我尝试了另一个解决方案,但因为这个问题有一个正确的答案,这不是我的主要目标


我看到你的帖子说一卡路里的差异是可以接受的,所以我建议创建一个函数,它的treshold为一卡路里,如果两个对象之间的差异小于treshold,则返回true

相关问题 更多 >

    热门问题