【问题标题】:Cannot define variable from one function into another one无法将变量从一个函数定义到另一个函数
【发布时间】:2020-12-08 01:32:53
【问题描述】:

我不能在另一个函数中使用来自一个函数的变量。 我正在尝试使用这两个:

    def b(df):
     macd=df['Close'].ewm(span=12, ignore_na=False).mean()- 
     df['Close'].ewm(span=26,ignore_na=False).mean() 
     return macd

    def b1(df):
     signal=df.rolling(window=9).mean()
     return signal

    def pls(df, macd, signal):
     macd=b(df)
     signal=b1(df)
     kodas(AMZN, macd, signal, 10000, 1, 1)
     balance=kodas(df, macd, signal, 10000, 1, 1)
     profitai=np.diff(balance)
     return macd, signal

但最终我收到此错误 name 'macd' is not defined 当我这样做时 pls(AMZN, macd, signal, balance, profitai)。我敢肯定,“信号”和“平衡”也会发生这种情况。我知道我没有在函数之外定义“macd”,但我不会为一个 STOCK 数据计算“macd”,所以我必须创建一个代码不会重复一千次的函数。所以,我的问题是在这种情况下我应该怎么做才能在另一个函数中使用来自一个函数的变量? 这是完整的代码:

from google.colab import drive
drive.mount('/content/drive')

import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.dates as mdates
import numpy as np
import matplotlib.lines as mlines

def failas(df):
 coltsla=['Date', 'Time' , 'Open', 'High', 'Low', 'Close', 'Volume']
 dateparse = lambda x: pd.datetime.strptime(x, '%m/%d/%Y %H:%M')
 df = pd.read_csv(df, parse_dates={'Datetime': ['Date', 'Time']}, header=0, names=coltsla)
return df

def failas1(df):
 coltsla=['Date', 'Time' , 'Open', 'High', 'Low', 'Close', 'Volume']
 dateparse = lambda x: pd.datetime.strptime(x, '%m/%d/%Y %H:%M')
 df = pd.read_csv(df, parse_dates={'Datetime': ['Date', 'Time']}, skiprows=2, header=0,names=coltsla)
 return df

AMZN=failas("/content/drive/My Drive/AMZN.csv")
AMZN1=failas1("/content/drive/My Drive/AMZN.csv")

def b(df):
 macd=df['Close'].ewm(span=12, ignore_na=False).mean()- 
 df['Close'].ewm(span=26,ignore_na=False).mean() 
 return macd

def b1(df):
 signal=df.rolling(window=9).mean()
 return signal

def kodas(df, macd, signal, pradzia=10000, buyk=1, macdk=1):
 a=pd.Series(df['Close'])

 balance=[]
 money=pradzia
 kiekis=0
 lieka=0
 uzdarbis=0
 perkame=0
 taxsuma=100

for i in range(1, len(df)):
#Pirkimas
 if (macd[i] > signal[i] and macd[i-1] <= signal[i-1]):
  kiekis=money//(a[i]*buyk) 
  perkame=a[i]*buyk*kiekis
  lieka=money-perkame
 #TakeProfit
 if (macd[i] < signal[i]*macdk and macd[i-1] >= signal[i-1]*macdk):
  parduodame=kiekis*(a[i])
  uzdarbis=parduodame-perkame+lieka-taxsuma
  money=money+uzdarbis
 #Stoploss
 if (macd[i] > signal[i] and macd[i-1] <= signal[i-1] and a[i] < (df['High'][i])*0.945 or macd[i] < 
  signal[i] and macd[i-1] >= signal[i-1] and a[i] < (df['High'][i])*0.945):  
  parduodame=kiekis*(a[i])
  uzdarbis=parduodame-perkame+lieka-taxsuma
  money=money+uzdarbis
 balance.append(money-10000)
return balance

def pls(df, macd, signal):
 macd=b(df)
 signal=b1(df)
 kodas(AMZN, macd, signal, 10000, 1, 1)
 balance=kodas(df, macd, signal, 10000, 1, 1)
 profitai=np.diff(balance)
 return macd, signal

pls(AMZN, macd, signal, balance, profitai)
plt.plot(AMZN1['Datetime'], profitai.cumsum())

【问题讨论】:

    标签: python undefined


    【解决方案1】:

    在您定义一个名为macd 的变量的任何地方,您都是在“函数范围”中定义它。这意味着该变量仅在该函数执行时才存在。当函数退出时,macd 变量就消失了。在某些情况下,您将 macd 定义为函数中的局部变量,而其他时候您将其定义为函数的参数,但结果是相同的。定义变量的两种方式都会导致它在单个函数的级别上定义,这意味着当函数结束时,该变量不再存在。所以你不能“在另一个函数中使用一个函数中定义的变量”。由于语言的范围规则,它不能那样工作。

    您尝试使用 macd 变量并得到错误的地方是“全局范围”。您尚未在该范围级别定义名为 macd 的变量。这就是您收到错误消息的原因。

    您需要想办法将您感兴趣的值放到全局范围内。您可以通过让其中一个函数将其作为函数的返回值返回来最好地做到这一点。然后,您可以将名为 macd 的全局变量设置为调用该函数的结果,然后您可以将该变量传递给 pls 函数。

    b 函数返回macd,但它需要一个参数df,您也没有在全局范围内定义它。但只是为了说明,假设您确实已经在全局范围内获得了 df 的值。那么您的代码可能如下所示:

    df = ???
    
    ...
    
    macd = b(df) # <- `macd` variable being defined at the global scope
    pls(AMZN, macd, signal, balance, profitai)
    plt.plot(AMZN1['Datetime'], profitai.cumsum())
    

    但是,此代码不会运行,因为pls 函数的其余参数以及profitai 的值也会遇到同样的问题。

    我认为您真正想做的是将pls 函数中的代码带到全局范围并删除该函数。此外,您可以通过调用failas1 获得df 的值。该函数接受值df 作为参数,这没有意义,因为该函数计算df 的值。因此,我们可以为该参数传入任何内容,因为它没有被使用。有了这些想法,我们提出了:

    df = failas1(None)
    
    macd = b(df)
    signal = b1(df)
    kodas(AMZN, macd, signal, 10000, 1, 1)
    balance = kodas(df, macd, signal, 10000, 1, 1)
    profitai = np.diff(balance)
    
    plt.plot(AMZN1['Datetime'], profitai.cumsum())
    

    您的代码中有一些缩进错误,我也必须修复。一旦我这样做了,并且像上面那样重新排列了代码的底部,那么所有的符号定义似乎都匹配得很好。我没有尝试运行代码。还有一些其他地方可以将参数传递给函数,然后让函数计算该值。在这些情况下,您可能希望从函数签名中删除参数。

    【讨论】:

    • 感谢@Steve 的帮助,但我已经尝试过您建议的代码。但我必须将这些函数用于 10 个数据帧,例如: AMZN=failas("/content/drive/My Drive/AMZN.csv") MSFT=failas("/content/drive/My Drive/MSFT.csv") NFLX= failas("/content/drive/My Drive/NFLX.csv") NKE=failas("/content/drive/My Drive/NKE.csv") OIL=failas("/content/drive/My Drive/OIL.csv ") ......因此,如果我要将该代码用于 10 个数据帧,我将不得不编写相同的代码 10 次,但只需更改 df 参数。但据我了解,这是在这种情况下的唯一方法?
    猜你喜欢
    • 1970-01-01
    • 2021-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多