Python nested classes: self is not defined - python

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()

Related

lack of understanding of the super() with parameters

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')

AttributeError: 'LoginViewModel' object has no attribute 'name'

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.

Don't know what I did wrong in class inheritance/special methods

I'm trying to solve a problem in my class, and I'm not sure what I'm doing wrong.
class Company:
def __init__(self, name=None):
self.name = name
class Travel(Company):
def __init__(self, name=None):
self.name = name
if name == None:
name = "Generic"
super().__init__(name)
def __str__(self, name=None):
self.name = name
return "Company name:{}".format(name)
def __repr__(self):
return "Travel('{self.name}')"
def set_name(self, new_name):
self.new_name = new_name
return new_name
bever = Travel('bever')
print(bever)
bever.set_name('beverly hills')
print(bever)
I want it to return
Company name: bever
Company name: beverly hills
but it just returns
Company name: None
Company name: None
any help is appreciated
You need to change a few things:
Check if name is None before you assign it to self.name
f"Travel('{self.name}')", you forgot to add an f while returning the string in __repr__
Assign new_name to self.name when you use .set_name()
class Company:
def __init__(self, name=None):
self.name = name
class Travel(Company):
def __init__(self, name=None):
if name == None:
name = "Generic"
self.name = name
super().__init__(name)
def __str__(self, name=None):
#self.name = name
return "Company name:{}".format(self.name)
def __repr__(self):
return f"Travel('{self.name}')"
def set_name(self, new_name):
self.name = new_name
return self.name
bever = Travel('bever')
print(bever)
bever.set_name('beverly hills')
print(bever)
This should do the trick
class Company:
def __init__(self, name=None):
self.name = name
class Travel(Company):
def __init__(self, name=None):
if name == None:
name = "Generic" # First set the local parameter
self.name = name # Then the attribute
super().__init__(name)
def __str__(self): # str() does not expect parameters
return f"Company name:{self.name}" # use the instance's attribute instead
def __repr__(self):
return f"Travel('{self.name}')"
def set_name(self, new_name):
self.name = new_name # Update the instance's attribute
return new_name
bever = Travel('bever')
print(bever)
bever.set_name('beverly hills')
print(bever)

Passing class parameters python

I have 2 classes
class Robot1:
def __init__(self, name):
self.name = name
def sayHi(self):
return "Hi, I am " + self.name
class Robot2:
def __init__(self, name):
self.name = name
def sayHello(self):
return "Hello, I am " + self.name
robot_directory = {1: Robot1(), 2: Robot2()}
def object_creator(robo_id, name):
robot_object = robot_directory[robo_id]
return robot_object
But I don't know how to pass the variable name while instantiating the class on the line robot_object = robot_directory[robo_id]. How can I pass the variable?
You are storing already-created instances in the dictionary. Store the class itself instead:
# ...
robot_directory = {1: Robot1, 2: Robot2}
def object_creator(robo_id, name):
robot_class = robot_directory[robo_id]
# Here, the object is created using the class
return robot_class(name)
Obviously, this requires that all your robot classes have the same __init__ parameters.
Going further, you might want to look into inheritance and use a common base class for your robots.
maybe you can try
class Robot1:
def __init__(self):
pass
def set_name(self, name):
return "Hi, I am " + name
class Robot2:
def __init__(self):
pass
def set_name(self, name):
return "Hello, I am " + name
robot_directory = {1: Robot1(), 2: Robot2()}
def object_creator(robo_id, name):
robot_object = robot_directory[robo_id]
return robot_object.set_name(name)

Using super() Multiple Times in a Python Class

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()))

Categories

Resources