I am a newbie to python and just started this week, and for the life of me I do not know where is the conflict: ValueError: ‘toEmailAddress’ in slots conflicts with class variable
Any help is great appreciated !
import sendgrid
import os
from sendgrid.helpers.mail import Mail, Email, To, Content
class SendNotification:
__slots__ = ("toEmailAddress", "fromEmailAddress")
def __init__(self, toEmailAddress, fromEmailAddress):
self.toEmailAddress = toEmailAddress
self.fromEmailAddress = fromEmailAddress
@property
def toEmailAddress(self):
return self._toEmailAddress
@toEmailAddress.setter
def toEmailAddress(self, toEmailAddress):
self._toEmailAddress = toEmailAddress
@property
def fromEmailAddress(self):
return self.fromEmailAddress
@fromEmailAddress.setter
def fromEmailAddress(self, fromEmailAddress):
self._fromEmailAddress = fromEmailAddress
def SendEmail(self):
apiKey = 'abc123'
sg = sendgrid.SendGridAPIClient(apiKey)
from_email = Email("myName@myCompany.com") # Change to your verified sender
to_email = To("yourName@yourCompany.com") # Change to your recipient
subject = "Sending with SendGrid is Fun"
content = Content("text/plain", "this is from allan")
mail = Mail(from_email, to_email, subject, content)
# Get a JSON-ready representation of the Mail object
mail_json = mail.get()
try:
# Send an HTTP POST request to /mail/send
response = sg.client.mail.send.post(request_body=mail_json)
print(response.status_code)
print(response.headers)
except Exception as e:
print(e)
#_____________
sendAlert = SendNotification("myName@myCompany.com", "yourName@yourCompany.com")
sendAlert.SendEmail()
```
That said, if your getters and setters are just read/writing underscored variables with no validation or transformation, you might as well just get rid of them and use standard attributes:
I assumed the setter was needed to update the class attribute.
Question: Since Python does not have class accessors (public, private, protected, internal), I think I saw this somewhere – the way to denote that an attribute is ‘private’ is like this: _attributeName
Or, the way to make an attribute private is with the property getter and setter and raised an ValueError?
Yes, you can make a variable “private” by convention by prefixing with an underscore. But that is just a way of you indicating that a downstream user can’t expect that variable to always exist or behave the way they expect. They can still set sendAlert._toEmailAddress = "whatever". Using properties allows you to let them set sendAlert.toEmailAddress = "whatever" and you can check that "whatever" is a valid email address before storing it. Or you could choose not to set a setter, which would be a way of adding friction to modifying an object in-place instead of through a standard method. If your getter/setter are just pass-through, they’re needless indirection.
If you’re used to private/public/protected, those concepts just don’t exist in Python, and they don’t really need to. I would suggest starting “radically open” and let your attributes be set by callers. As you find a need to validate/modify inputs, then you can start shifting things into properties, but I think you’ll find you don’t need it as much as you might think, if you’re coming from a language where private variables are standard.