i am new to programming, and based on what i've read so far,i thought that the super() method was viewed by python as super(class,self). so if i was inheriting from 2 parent classes, i could pass the class i want the super method to reference directly into super(). however when i do this, i get tracebacks that i cant understand.
the following 2 codes are what i tried that resulted in traceback
class Employee:
new_id = 1
def __init__(self):
self.id = Employee.new_id
Employee.new_id += 1
class User:
def __init__(self, username, role="Customer"):
self.username = username
self.role = role
class Admin(Employee,User):
def __init__(self):
super(Employee,self).__init__()
super(User,self).__init__(self,self.id,'admin')
e1 = Employee()
e2 = Employee()
e3 = Admin()
------------------
class Employee:
new_id = 1
def __init__(self):
self.id = Employee.new_id
Employee.new_id += 1
class User:
def __init__(self, username, role="Customer"):
self.username = username
self.role = role
class Admin(Employee,User):
def __init__(self):
Employee.__init__()
User.__init__(self,self.id,'admin')
e1 = Employee()
e2 = Employee()
e3 = Admin()
i want to understand why the code above results in tracebacks, because from what i understood, i am still calling the init method of the parentclass in each one.
class Employee:
new_id = 1
def __init__(self):
self.id = Employee.new_id
Employee.new_id += 1
class User:
def __init__(self, username, role="Customer"):
self.username = username
self.role = role
class Admin(Employee,User):
def __init__(self):
super().__init__()
User.__init__(self.id,'admin')
Related
In my flask application, i want to call attribute from parent class, but each time AttributeError exception is occuring, i do not know why it is happening. i'm currently using python 3.9.9 in my linux enviroment and pyenv.
class ViewModelBase:
def __init__(self):
self.name = "expense_tracker"
self.user_id: Optional[str] = current_user.get_id()
self.request: Request = flask.request
self.request_dict = request_dict.create('')
self.success: str
def to_dict(self):
return self.__dict__
class ViewModelBaseUser(ViewModelBase):
def __init__(self):
super().__init__()
self.user_name = self.request_dict.user_name.strip()
self.email = self.request_dict.email.lower().strip()
self.first_name = self.request_dict.first_name.strip()
self.second_name = self.request_dict.second_name.strip()
self.country = self.request_dict.country
self.countries = country_service.all_countries()
class LoginViewModel(ViewModelBase, ViewModelDataValidator):
def __init__(self):
super(ViewModelDataValidator, self).__init__()
super(ViewModelBase, self).__init__()
self.login = self.request_dict.login.lower().strip()
self.password = self.request_dict.password.strip()
self.remember_login = self.request_dict.remember_login == 'on'
def validate(self):
if not self.login:
self.error.append(gettext(""))
if not self.password:
self.error.append(gettext(""))
def value_name(self):
return self.name
ok... i found the problem, even if i called super for init from both parent classes only one super().init() was required and everything is working fine.
It is my second-day learning object-oriented programming.
I have a code which when I create a instance it should automatically be added to another class.
The way Iam asking may be wrong so apologies.
class Name:
def __init__(self, first, last):
self.first = first
self.last = last
class Pet:
def __init__(self, name, owner):
self.name = name
self.owner = owner
class Owner:
def __init__(self, name):
self.name = name
self.pets = []
How should I modify the classes above so that when a new instance of Pet
is created, it is automatically added to its Owner's list of
pets.
for example: if I created the instances below
owner_1 = Owner(Name("Daenerys", "Targaryan"))
owner_2 = Owner(Name("John", "Snow"))
pet_1 = Pet(Name("Drogon", "Targaryan"), owner_1)
pet_2 = Pet(Name("Viserion", "Targaryan"), owner_1)
pet_3 = Pet(Name("Rhaegal", "Snow"), owner_2)
Owner.pets will return a list of pets of an owner
i.e for Daenerys, the list will be ["Drogon Targaryan", "Viserion Targaryan"]
You can do something like this
class Name:
def __init__(self, first, last):
self.first = first
self.last = last
class Pet:
def __init__(self, name, owner):
self.name = name
self.owner = owner
self.owner.add_pet(self)
class Owner:
def __init__(self, name):
self.name = name
self.pets = []
def add_pet(self, pet):
self.pets.append(pet)
I would like to do the following things:
user = Get()
user.username
user.youtube.name
user.youtube.subs
user.twitter.name
user.twitter.subs
user.twitter.open()
This is the code I have:
class Get():
def __init__(self, username):
self.username = username
class youtube:
self.name = "NameOfTheUserOnYoutube"
self.subs = 123456
class twitter:
def open():
webbrowser.open("https://www.twitter.com/NameOfTheUserOnTwitter")
self.name = "NameOfTheUserOnTwitter"
self.subs = 654321
But when I execute this, the following error occurs:
File "mycode.py", line 9, in youtube
self.name = "NameOfTheUserOnYoutube"
NameError: name 'self' is not defined
A nested class is not automatically an attribute. You need to create attributes as well, and call the class to create instances.
class Get():
def __init__(self, username):
self.username = username
self.youtube = Get.Youtube()
self.twitter = Get.Twitter()
class Youtube:
def __init__(self):
self.name = "NameOfTheUserOnYoutube"
self.subs = 123456
class Twitter:
def __init__(self):
self.name = "NameOfTheUserOnTwitter"
self.subs = 654321
def open(self):
webbrowser.open("https://www.twitter.com/" + self.name)
user = Get('barmar')
print(user.username)
print(user.youtube.name, user.youtube.subs)
print(user.twitter.name, user.twitter.subs)
user.twitter.open()
Trying to understand super() I made these two examples but they return the same results.
This is with super()
class Person1():
def __init__(self, name):
self.name = name
class EmailPerson1(Person1):
def __init__(self, name, email):
super().__init__(name)
self.email = email
bob2 = Person('Dim')
bob = EmailPerson1('Bob Frapples', 'bob#frapples.com')
bob.name
'Bob Frapples'
and this without super()
class Person():
def __init__(self, name):
self.name = name
class EmailPerson(Person):
def __init__(self, name, email):
self.name = name
self.email = email
bob2 = Person('Dim')
bob1 = EmailPerson('Bob Frapples', 'bob#frapples.com')
bob1.name
'Bob Frapples'
What is the difference? The first version should use the name from the parent class I think.
The difference is you are manually duplicating the work done by Person.__init__ in EmailPerson.__init__, instead of using super().__init__ to make sure the inherited initializer does what it needs to.
class Person():
def __init__(self, name):
self.name = name
class EmailPerson(Person):
def __init__(self, name, email):
self.name = name
self.email = email
Using super, i.e.,
class EmailPerson(Person):
def __init__(self, name, email):
super().__init__(name)
self.email = email
means that if someone updated the definition of Person to do some additional work in Person.__init__:
class Person:
def __init__(self, name):
self.name = name.title() # bob grapples -> Bob Frapples
you don't need to update the definition of EmailPerson at all to take advantage of the new change.
Why does user.params() not return all the params up the inheritance
chain? -- It's not including the params defined in Person() -- notice
Vertex() does not have a params() method.
class Element(object):
def __init__(self,element_type):
self.oid = None
self.uuid = uuid.uuid4()
self.key = None
self.element_type = element_type
def params(self):
return dict(uuid=self.uuid, key=self.key)
class Vertex(Element):
def __init__(self):
super(Vertex,self).__init__("vertex")
class Person(Vertex):
def __init__(self,name=None,uri=None,email=None):
self.s = super(Person,self)
self.s.__init__()
self.name=name
self.uri=uri
self.email = email
def params(self):
params = dict(name=self.name,uri=self.uri,email=self.email)
params.update(self.s.params())
return params
class User(Person):
def __init__(self,
name=None,
uri=None,
email=None,
first_name=None,
last_name=None,
facebook_id=None,
facebook_link=None,
facebook_username=None,
gender=None,
locale=None):
self.s = super(User,self)
self.s.__init__(name,uri,email)
self.first_name = first_name
self.last_name = last_name
self.facebook_id = facebook_id
self.facebook_link = facebook_link
self.facebook_username = facebook_username
self.gender = gender
self.locale = locale
def params(self):
params = dict(first_name=self.first_name,
last_name=self.last_name,
facebook_id=self.facebook_id,
facebook_link=self.facebook_link,
facebook_username=self.facebook_username,
gender=self.gender,
locale=self.locale)
print self.s.params()
params.update(self.s.params())
return params
In User you do:
self.s = super(User,self)
self.s.__init__(name,uri,email)
so self.s is what? As you do the same in Person, self.s is super(Person) and that anywhere, in Person and User as you reassign self.s, so the self.s.params that gets picked is the one of Element.
edit : also the following code works, Sebastians has the correct interpretation: self.s is reassigned each time in the __init__ of the classes. So self.s is reassigned as super(Person,self).
import uuid
class Element(object):
def __init__(self,element_type):
self.oid = None
self.uuid = uuid.uuid4()
self.key = None
self.element_type = element_type
def params(self):
print 'here Element'
return dict(uuid=self.uuid, key=self.key)
class Vertex(Element):
def __init__(self):
super(Vertex,self).__init__("vertex")
class Person(Vertex):
def __init__(self,name=None,uri=None,email=None):
super(Person,self).__init__()
self.name=name
self.uri=uri
self.email = email
def params(self):
print 'here Person'
params = dict(name=self.name,uri=self.uri,email=self.email)
params.update(super(Person,self).params())
return params
class User(Person):
def __init__(self,
name=None,
uri=None,
email=None,
first_name=None,
last_name=None,
facebook_id=None,
facebook_link=None,
facebook_username=None,
gender=None,
locale=None):
super(User,self).__init__(name,uri,email)
self.first_name = first_name
self.last_name = last_name
self.facebook_id = facebook_id
self.facebook_link = facebook_link
self.facebook_username = facebook_username
self.gender = gender
self.locale = locale
def params(self):
params = dict(first_name=self.first_name,
last_name=self.last_name,
facebook_id=self.facebook_id,
facebook_link=self.facebook_link,
facebook_username=self.facebook_username,
gender=self.gender,
locale=self.locale)
print 'here User'
params.update(super(User, self).params())
return params
if __name__ == '__main__':
u = User()
print '\n'.join(sorted(u.params().keys()))