无法从自定义python模块导入类

时间:2019-05-01 15:28:05

标签: python

有一个空白的NatMailer/__init__.py

在这里: NatMailer/NatMailer.py

# python -m smtpd -n -c DebuggingServer localhost:1025
class NatMailer:
    def __init__(self, smtp_server="localhost", port=1025, sender_email="example@example.com", debug=0):
        import logging

        logging.basicConfig(filename='example.log', level=logging.DEBUG)
        logging.info("Initiating NatMailer")

        import smtplib, ssl
        import json
        import csv
        import sqlite3

        sql = sqlite3.connect('example.db')
        self.debug = debug
        if (debug):
            self.smtp_server = "localhost"
            self.port = 1025
            self.sender_email = "example@example.com"
        else:
            self.smtp_server = smtp_server
            self.port = port
            self.sender_email = sender_email
    def send_email(self, receiver_email, message_contents):
        # Create a secure SSL context
        context = ssl.create_default_context()
        logging.info("Sending new email")

        # Try to log in to server and send email
        try:
            server = smtplib.SMTP(self.smtp_server,self.port)
            server.ehlo() # Can be omitted
            if (not self.debug):
                logging.info("Logging into " + self.sender_email)
                server.starttls(context=context) # Secure the connection
                server.ehlo() # Can be omitted
                server.login(self.sender_email, self.password)
            logging.info("Sending email to " + receiver_email)
            server.sendmail(self.sender_email, receiver_email, message_contents)
        except Exception as e:
            # Print any error messages to stdout
            logging.debug(e)
        finally:
            server.quit()

然后在debug_driver.py外面有一个NatMailer/

import NatMailer
debug = 1
nm = NatMailer.NatMailer(debug=debug)
message = """\
            Subject: Hi there

            This message is sent from Python."""
nm.send_email('someone@gmail.com', message)

我收到此错误:

Traceback (most recent call last):
  File "C:/Users/pat/PycharmProjects/NatMailer/debug_driver.py", line 3, in <module>
    nm = NatMailer.NatMailer(debug=debug)
AttributeError: module 'NatMailer' has no attribute 'NatMailer'

Process finished with exit code 1

我在做什么错?我希望能够将自定义类导入到debug_driver.py脚本中。

1 个答案:

答案 0 :(得分:2)

这里涉及三个级别:目录(包),文件名(模块)和类。 NatMailer表示包,NatMailer.NatMailer表示模块,NatMailer.NatMailer.NatMailer表示类。

所以您需要类似的东西

# import module from package
import NatMailer.NatMailer  

debug = 1
nm = NatMailer.NatMailer.NatMailer(debug=debug)

错误消息的简要说明:

AttributeError: module 'NatMailer' has no attribute 'NatMailer'

您仅导入软件包(或模块,如此处所述):

import NatMailer

基本上,这只会加载__init__.py文件,该文件为空。因此,当您尝试访问该模块的任何内容时,Python都会抱怨,因为那里什么也没有:

NatMailer.NatMailer

该属性不存在:它不是(sub)模块,因为它不是在__init__.py中导入的,也不是类,因为它也不是在__init__.py中导入的。基本上,这几乎是空的导入,您必须显式导入NatMailer.NatMailer。但请参见上方和下方。


替代品:

1 /

# import module from package
from NatMailer import NatMailer  

debug = 1
nm = NatMailer.NatMailer(debug=debug)

2 /

# import class from the module directly
from NatMailer.NatMailer import NatMailer  

debug = 1
nm = NatMailer(debug=debug)

3 /也许涉及更多,但经常使用:

将其放入您的包裹__init__.py

from .NatMailer import NatMailer

然后使用

# import the class from package
# note: now you can't distinguish the class from the module.
# see the remark at the bottom about naming conventions
from NatMailer import NatMailer  

debug = 1
nm = NatMailer(debug=debug)

由于NatMailer类现在可以在包级别而不是模块级别找到。


注意:软件包和模块通常不使用CamelCased。这会使事情变得更有洞察力:natmailer.natmailer.NatMailer将是您的课程。