首页 > 解决方案 > 导入带有常量的文件并抛出 AttributeError [Python 3]

问题描述

我正在 Python 3 中制作一个货币转换器程序,同时尝试稍微清理我的代码,因此决定将我的常量保存在一个名为settings.py的单独文件中,然后在使用常量的地方导入设置。

我以前在以前的项目中做过这个,但由于某种原因,它现在不想工作并且很难找到原因。请记住,我只是一个初学者。

包括回溯的错误是:

 : [MSG] : Starting up...
Traceback (most recent call last):
  File "main.py", line 1, in <module>
    import settings
  File "D:\Work\Programming\Python\Independent\CurrencyConverter\settings.py", line 3, in <module>
    import main
  File "D:\Work\Programming\Python\Independent\CurrencyConverter\main.py", line 82, in <module>
    getData()
  File "D:\Work\Programming\Python\Independent\CurrencyConverter\main.py", line 9, in getData
    da.getFile()
  File "D:\Work\Programming\Python\Independent\CurrencyConverter\dataAccquisition.py", line 22, in getFile

    if isDataOld():
  File "D:\Work\Programming\Python\Independent\CurrencyConverter\dataAccquisition.py", line 10, in isDataOld
    if os.path.isfile(settings.FILE):
AttributeError: module 'settings' has no attribute 'FILE'

数据采集​​.py

#Currency conversions - dataAccquisition.py

import settings
import requests
from xml.etree import cElementTree as ET
import os
import time

def isDataOld():
    if os.path.isfile(settings.FILE):
        fileTime = os.path.getmtime(settings.FILE)
        if (time.time() - fileTime) / 3600 > 24*1:
            print(' : [MSG] : Data is old.')
            return True
        else:
            print(' : [MSG] : Data is up to date.')
            return False
    print(' : [MSG] : Data does not exist.')
    return True

def getFile():
    if isDataOld():
        print(' : [MSG] : Finding and downloading data from URL.')
        r = requests.get(settings.URL, allow_redirects=True)
        open('exData.xml', 'wb').write(r.content)

def parseData():
    print(' : [MSG] : Starting to parse data...')
    tree = ET.ElementTree(file=settings.FILE)
    root = tree.getroot()
    datalist_currency = []
    datalist_rates    = []
    print(' : [MSG] : Adding currency and rates to datalist=')
    for child in root:
        for subchild in child:
            for subsubchild in subchild:
                print(' : [MSG] : Adding currency',subsubchild.attrib['currency'])
                datalist_currency.append(subsubchild.attrib['currency'])
                print(' : [MSG] : with rate',subsubchild.attrib['rate'])
                datalist_rates.append(subsubchild.attrib['rate'])

    datalist_zip = dict(zip(datalist_currency, datalist_rates))
    print(' : [MSG] : Done parsing data!')
    return datalist_zip

设置.py

#Currency conversions - settings.py

import main
import os

URL      = "https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml"
DIR      = os.path.dirname(os.path.realpath(__file__))
FILE     = os.path.join(DIR, 'exData.xml')

OPTIONS = {'USD' : main.toUSD, 'JPY' : main.toJPY, 'BGN' : main.toBGN, 'CZK' : main.toCZK,
           'DKK' : main.toDKK, 'GBP' : main.toGBP, 'HUF' : main.toHUF, 'PLN' : main.toPLN,
           'RON' : main.toRON, 'SEK' : main.toSEK, 'CHF' : main.toCHF, 'ISK' : main.toISK,
           'NOK' : main.toNOK
}

我的目录结构如下:

$ tree
.
├── dataAccquisition.py
├── main.py
├── settings.py
├── exData.xml

0 Directories, 4 files

主文件

import settings
import dataAccquisition as da

data = []

def getData():
    global data
    print(' : [MSG] : Starting up...')
    da.getFile()
    data = da.parseData()
    print(' : [MSG] : Start up done, ready to be used.')

def getRate(currencyName):
    return data[currencyName]

def menu():
    def text():
        print('''\n----------------MENU----------------
-    0. Convert currency           -
-    1. Display all rates          -
-    2. Retry to download data     -
-    3. Quit                       -
------------------------------------''')
    run = True
    while run:
        text()
        choice = input('s: ')
        if choice == '0':
            for currency, rates in data.items():
                print("'"+str(currency)+"'",":","to"+str(currency)+",")
        elif choice == '1':
            for currency, rates in data.items():
                print(currency,':', rates)
        elif choice == '2':
            getData()
        elif choice == '3':
            run = False
            # sys.quit()
        else:
            print(' : [MSG] : No such choice!')
            choice = input('s: ')

def toUSD():
    pass

def toJPY():
    pass

def toBGN():
    pass

def toCZK():
    pass

def toDKK():
    pass

def toGBP():
    pass

def toHUF():
    pass

def toPLN():
    pass

def toRON():
    pass

def toSEK():
    pass

def toCHF():
    pass

def toISK():
    pass

def toNOK():
    pass

getData()
menu()

标签: pythonpython-3.x

解决方案


感谢 user2357112 对循环导入发表了评论。这帮助我弄清楚我做错了什么。

通过导入设置,然后导入 main,这将导致 main 再次运行,因此我们有一个循环导入导致错误。

我还没有足够的知识知道可以做些什么来解决这个问题,所以我可以将我的 OPTIONS 保留在设置中,并且仍然可以访问 main 中的功能。但此时我已着手将 OPTIONS 保留在 main.py 中,并且可能会在以后返回尝试学习如何操作。


推荐阅读