Using super() Multiple Times in a Python Class - python

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

Related

Python classmethod with inheritance

Could someone explain to me how to correctly use classmethod with inheritance in Python?
I need to create two classmethod methods:
to makefull-timeime employee.
to make a part-time employee in Employee class which is inhering from BaseEmployee.
Seem that I fully don't understand a concept:(
Ok, so the question is how to properly create a classmethod and then
how to create a fulltime employee?
Thanks
from datetime import datetime
class Error(Exception):
"""Base class for exception"""
pass
class InvalidDateOfEmployment(Error):
"""Except bigger date then today and seniority more than 50 years"""
pass
class Application:
#staticmethod
def main(self):
name = input('Name: ')
last_name = input('Last name: ')
date_of_employement = datetime.strptime(input('Date of Employement (2022-03-02): '), '%Y.%m.%d')
if Application.date_of_employment_validation(datetime.today(), date_of_employement):
raise InvalidDateOfEmployment
employee = BaseEmployee(name, last_name, date_of_employement)
#staticmethod
def date_of_employment_validation(today: datetime, date: datetime):
diff = today - date
diff_in_years = round(diff.days / 365.25)
return 50 > diff_in_years > 0 #diff_in_years < 50 and diff_in_years > 0
class BaseEmployee:
def __init__(self, name, last_name, date_of_employement):
self.name = name
self.last_name = last_name
self.date_of_employement = date_of_employement
self.now = datetime.now()
#property
def employment_time(self):
return (self.now - self.date_of_employement).days
def __lt__(self, other):
return self.employment_time < other.employment_time
def __repr__(self):
return self.name, self.last_name, self.date_of_employement
class Employee(BaseEmployee):
def __init__(self, bonus, type_of_employment, hour_pay_rate, name, last_name, date_of_employement):
super().__init__(name, last_name, date_of_employement)
self.bonus = bonus
self.type_of_employment = type_of_employment
self.hour_pay_rate = hour_pay_rate
#classmethod
def create_fulltime(cls, bonus, type_of_employment, hour_pay_rate):
return cls(bonus, 160, hour_pay_rate)
# #classmethod
# def create_partime(cls, name, last_name, date_of_employement, bonus, hour_pay_rate):
# return cls(name, last_name, date_of_employement, bonus, hour_pay_rate, 80)
def calculate_sallary(self):
return self.hour_pay_rate * self.type_of_employment + self.bonus
if __name__ == '__main__':
Application.main()
def test_sort_employees():
#given
a = BaseEmployee('A', 'A', datetime(2020, 12, 10))
b = BaseEmployee('B', 'B', datetime(2020, 10, 10))
employees = [a, b]
#when
sorted_employees = sorted(employees)
#then
assert sorted_employees[0] == a
For example:
from datetime import datetime
class Employee:
bonus = 1
base_hpr = 300
#classmethod
#property
def salary_bonus_multiplier(cls):
return cls.bonus
def __init__(self, name, last_name, date_of_employement, hour_pay_rate = base_hpr):
self.name = name
self.last_name = last_name
self.date_of_employement = date_of_employement
self.hour_pay_rate = hour_pay_rate
self.now = datetime.now()
#property
def employment_time(self):
return (self.now - self.date_of_employement).days
def calculate_sallary(self):
return self.employment_time * self.hour_pay_rate * self.salary_bonus_multiplier
def __lt__(self, other):
return self.employment_time < other.employment_time
def __repr__(self):
return self.name, self.last_name, self.date_of_employement
class HalfTimeEmployee(Employee):
bonus = 0.5
class FullTimeEmployee(Employee):
pass
if __name__ == '__main__':
a = HalfTimeEmployee('A', 'A', datetime(2020, 10, 10))
b = FullTimeEmployee('B', 'B', datetime(2020, 10, 10))
print(a.calculate_sallary(), b.calculate_sallary())
classmethod mean to use only class avaluable variables.
Inheritance helps to change them in a particular case.

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)

Python nested classes: self is not defined

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

My code keeps getting a "Name 'breed' is not defined" error

My error is:
NameError: name 'breed' is not defined
but I thought it was defined in the __init__ function? Any suggestions? This is code from a study guide for an exam, and I'm trying to input it into python 2.7 myself to see the output.
class Dog(object):
def __init__(self, breed, owner = "pound"):
self.owner = owner
self.breed = breed
#property
def owner(self):
return self._owner
#owner.setter
def owner(self, value):
self._owner = value
#breed.setter
def breed(self, value):
self._breed = value
def __str__(self):
return "Breed = {}, \tOwner = {}".format(\
self.breed, self.owner)
d1 = Dog("Beagle")
d2 = Dog("Rottweiler", "James")
d3 = Dog("Poodle")
print "d1: {}".format(d1)
print "d2: {}".format(d2)
print "d3: {}".format(d3)
You should have had #property for breed as well:
class Dog(object):
def __init__(self, breed, owner = "pound"):
self.owner = owner
self.breed = breed
#property
def owner(self):
return self._owner
#owner.setter
def owner(self, value):
self._owner = value
#property
def breed(self):
return self.breed
#breed.setter
def breed(self, value):
self._breed = value
def __str__(self):
return "Breed = {}, \tOwner = {}".format(\
self.breed, self.owner)
d1 = Dog("Beagle")
d2 = Dog("Rottweiler", "James")
d3 = Dog("Poodle")
print "d1: {}".format(d1)
print "d2: {}".format(d2)
print "d3: {}".format(d3)

Python Global Variables in Class?

I have a list of instances of my Business class. I'm used to defining the variables for a class at the top of the class. On of the variables in the Business class is a list of tags. When I loop through the list of businesses some have tags, some don't. Out of the 20 businesses the 4th element in the list has 4 tags. After these tags are added to this business all following instances of Business also share these tags. Here is my Business class-
from tag import *
class Business:
name = ""
website = ""
phone = ""
address = ""
city = ""
state = ""
postalCode = ""
tags = []
data = {}
def __init__(self, name):
self.setName(name)
# Modifiers
def setName(self, name):
self.name = name
def setWebsite(self, website):
self.website = website
def setPhone(self, phone):
self.phone = phone
def addTag(self, Tag):
self.tags.append(Tag)
def setAddress(self, address):
self.address = address
def setCity(self, city):
self.city = city
def setState(self, state):
self.state = state
def setPostalCode(self, postalCode):
self.postalCode = postalCode
def set(self, key, value):
self.data[key] = value
def unset(self, key):
del self.data[key]
# Accessors
def getWebsite(self):
return self.website
def getName(self):
return self.name
def getPhone(self):
return self.phone
def getTags(self):
return self.tags
def getAddress(self):
return self.address
def getCity(self):
return self.city
def getState(self):
return self.state
def getPostalCode(self):
return self.postalCode
def get(self, key):
return self.data[key]
def getKeys(self):
return self.data.keys()
# Helpers
And a tag is added to a business like this-
if len(categories) > 1:
for cat in categories:
B.addTag(Tag(cat))
Are the variables defined at the top of my business class global to all instances of Business? How do I fix this problem?
Yes, mutables assigned that way are "global" to the class. To make them "local," define them as instance variables. To do this for tags, for example, remove the global definition that you have and add instead a line to __init__ like:
def __init__(self, name):
self.setName(name)
self.tags = []
This assigns that value of tags to self rather than to the class generally.
You should be doing it this way instead:
from tag import *
class Business:
def __init__(self, name, website='', phone='', address='', city='', state='', postal_code='', tags=None, data=None):
self.name = name
self.website = website
self.phone = phone
self.address = address
self.city = city
self.state = state
self.postal_code = postal_code
self.tags = []
if tags is not None:
for tag in tags:
self.add_tag(tag)
self.data = {} if data is None else data
def add_tag(self, tag):
if not isinstance(tag, Tag):
tag = Tag(tag)
self.tags.append(tag)
def add_data(self, key, value):
self.data[key] = value
def remove_data(self, key):
del self.data[key]
def get_data(self, key):
return self.data[key]
def get_data_keys(self):
return self.data.keys()
Python generally avoids getters and setters unless some extra processing or error-checking is required

Categories

Resources