Reputation: 865
There is a blank NatMailer/__init__.py
.
Here's:
NatMailer/NatMailer.py
# python -m smtpd -n -c DebuggingServer localhost:1025
class NatMailer:
def __init__(self, smtp_server="localhost", port=1025, sender_email="[email protected]", 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 = "[email protected]"
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()
Then there is a debug_driver.py
outside of NatMailer/
.
import NatMailer
debug = 1
nm = NatMailer.NatMailer(debug=debug)
message = """\
Subject: Hi there
This message is sent from Python."""
nm.send_email('[email protected]', message)
I get this error:
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
What am I doing wrong? I want to be able to import a custom class into my debug_driver.py script.
Upvotes: 0
Views: 1490
Reputation: 12261
There are three levels involved here: directory (package), filename (module), and class. NatMailer
refers to the package, NatMailer.NatMailer
refers to the module, and NatMailer.NatMailer.NatMailer
refers to the class.
So you would need something like
# import module from package
import NatMailer.NatMailer
debug = 1
nm = NatMailer.NatMailer.NatMailer(debug=debug)
Brief explanation of the error message:
AttributeError: module 'NatMailer' has no attribute 'NatMailer'
You import just the package (or module, as stated here):
import NatMailer
That basically only loads the __init__.py
file, which is empty. Hence, when you try to access anything of that module, Python will complain, because there is nothing there:
NatMailer.NatMailer
The attribute doesn't exist: it's not the (sub)module, because that isn't imported in __init__.py
, nor is it the class, since that wasn't imported in __init__.py
either. It's basically a near-empty import, and you'd have to explicitly import NatMailer.NatMailer
. But see above and below.
Alternatives:
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/ Slight more involved perhaps, but quite often used:
Put this in your package __init__.py
:
from .NatMailer import NatMailer
and then use
# 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)
Since the NatMailer
class can now be found at package level, not just at module level.
Note: packages and modules are usually not CamelCased. That would make things slightly more insightful: natmailer.natmailer.NatMailer
would be your class.
Upvotes: 2