#C:/Python32
class Person:
def __init__(self, name = "joe" , age= 20 , salary=0):
self.name = name
self.age = age
self.salary = salary
def __printData__(self):
return " My name is {0}, my age is {1} , and my salary is {2}.".format(self.name, self.age, self.salary)
print(Person)
class Employee(Person):
def __init__(self, name, age , salary ):
Person. __init__ (self,name = "Mohamed" , age = 20 , salary = 100000)
def __printData__(self):
return " My name is {0}, my age is {1} , and my salary is {2}.".format(self.name, self.age, self.salary)
print(Employee)
p= Person()
e = Employee()
Your problem can be simplified to:
class Person:
print(Person)
This will raise a NameError. When constructing a class, the body of the class is executed and placed in a special namespace. That namespace is then passed to type which is responsible for actually creating the class.
In your code, you're trying to print(Person) before the class Person has actually been created (at the stage where the body of the class is being executed -- Before it gets passed to type and bound to the class name) which leads to the NameError.
It appears that you want to have your class return certain information when print is called on it, and that you also want that information printed when you create an instance of that class. The way you would do this is to define a __repr__ ( or __str__, for more on that see Difference between __str__ and __repr__ in Python ) method for your class. Then everytime print is called on an instance of your class, it will print what is returned by that __repr__ method. Then you can just add a line to your __init__ method, that prints the instance. Within the class, the current instance is referred to by the special self keyword, the name of the class is only defined outside the scope of the class, in the main namespace. So you should call print(self) and not print(Person). Here's some code for your example:
class Person:
def __init__(self, name = "joe" , age= 20 , salary=0):
self.name = name
self.age = age
self.salary = salary
print(self)
def __repr__(self):
return " My name is {0}, my age is {1} , and my salary is {2}.".format(self.name, self.age, self.salary)
joe = Person()
>>> My name is joe, my age is 20 , and my salary is 0.
Related
I'm messing around with classes and data flow and I am having difficulties creating a list of classes inside the class (to give control of the list to the class in itself).
class Person:
listOfPeople = []
def __init__(self, name, age):
self.name = name
self.age = age
self.listOfPeople = []
def set_age(self, age):
if age <= 0:
raise ValueError('The age must be positive')
self._age = age
def get_age(self):
return self._age
def AppendList(self):
self.listOfPeople.append(self)
def returnList(self):
return self.listOfPeople
age = property(fget=get_age, fset=set_age)
john = Person('John', 18)
barry = Person("Barry", 19)
john.AppendList()
barry.AppendList()
print(Person.listOfPeople)
The output is simply
[]
Let´s use this example. I want the class Person to have a list of people. That list of people has instances of the class it's in. I want the entire program to have access to this class, regardless of having an instance initialised. Is it even possible to do what I want in Python?
My expected output is a list with the 2 instances I added to the list.
Okay so you need to create the list outside the definitions first.
Then you need to change the append function to this instead, self.listOfPeople.append(self) so that the variables are added into the list when you run it your way and remove the self.listOfPeople from the __init__.
Now the listOfPeople you initialized is shared between all instances.
class Person:
listOfPeople = []
def __init__(self, name, age):
self.name = name
self.age = age
def set_age(self, age):
if age <= 0:
raise ValueError('The age must be positive')
self._age = age
def get_age(self):
return self._age
def AppendList(self):
self.listOfPeople.append(self)
def returnList(self):
return self.listOfPeople
age = property(fget=get_age, fset=set_age)
john = Person('John', 18)
barry = Person("Barry", 19)
john.AppendList()
barry.AppendList()
print(Person.listOfPeople)
for i in Person.listOfPeople:
print (i.name, i.age)
Output for first part is:
[<__main__.Person object at 0x7fcb72395150>, <__main__.Person object at 0x7fcb723954d0>]
Output for the second part is:
John 18
Barry 19
this code automatically adds new instances to Person.listOfPeople
class Person:
listOfPeople = []
def __init__(self, name, age):
self.name = name
self.age = age
Person.listOfPeople.append(self)
def set_age(self, age):
if age <= 0:
raise ValueError('The age must be positive')
self._age = age
def get_age(self):
return self._age
def AppendList(self):
self.listOfPeople.append(self)
def returnList(self):
return self.listOfPeople
def __repr__(self): #I've added __repr__
return self.name+' '+str(self.age)
age = property(fget=get_age, fset=set_age)
john = Person('John', 18)
barry = Person("Barry", 19)
# john.AppendList()
# barry.AppendList()
print(Person.listOfPeople)
the output: [John 18, Barry 19]
is this what you need?
Just get rid of this
self.listOfPeople = []
This line overrides the class attribute and creates an instance attribute with the same name - not what you want.
So for instance I have a class called Employee and I have a class method designed to raise the wage of an an Employee.
I just have issues actually getting my desired raise for the wage passed into the class method as an argument, it's baffling me.
Class module;
Class Employee:
def __init__(self, name, salary, age):
self.name = name.title()
self.salary = salary
self.age = age
def raise_wage(self, raise):
self.salary = self.salary + raise
main module;
def main():
e1 = Employee("John Smith", 50000, 42)
Employee.e1.raise_wage(500)
Passing that 500 in as an arguement is the issue, i get missing positional argument errors for the method etc.
How do I pass the argument to the class method?
Hope this makes sense.
You can't use raise. It is a reserved word.
Use class instead of Class to define a class.
Write e1.raise_wage() instead of Employee.e1.raise_wage().
class Employee:
def __init__(self, name, salary, age):
self.name = name.title()
self.salary = salary
self.age = age
def raise_wage(self, amount):
self.salary = self.salary + amount
e1 = Employee("John Smith", 50000, 42)
e1.raise_wage(500)
print(e1.salary) # output: 50500
raise is a reserved keyword used to raise an exception, change it to other name and it will work just fine.
https://www.w3schools.com/python/ref_keyword_raise.asp
raise is a reserved keyword in python for raising exception. use another name for that argument then it will work. And you already created object for Employee so no need to call function with class name again.
I'm creating an instance called Dog1. I'm curious what's the best practice in referencing objects.
Would I refer them later on in the class by self.breed or just by the object name breed.
For example in the print function below would I put in print(f"My name's {self.name}) or print(f"My name's {name})
class Dog:
def __init__(self, name, age, breed):
self.name = name
self.age = age
self.breed = breed
print(f"My name's {name}")
In later functions, you would refer to your variables as self.name. For example, you could do this:
class Dog:
def __init__(self, name, age, breed):
self.name = name
self.age = age
self.breed = breed
print(f"My name's {self.name}")
def print_breed(self):
print(f"I'm a {self.breed}")
dog = Dog("Fido", 10, "spaniel") # >>> My name's Fido
dog.print_breed() # >>> I'm a spaniel
Here, when you call dog.print_breed(), where dog is a variable instance of the Dog class, you would get back what the dog's breed is.
class Dog:
def __init__(self, name, age, breed):
self.name = name + '-sss-'
self.age = age
self.breed = breed
print(f"My name's {name}")
print(f"My name's {self.name}")
def s(self):
print(self.name)
try:
print(name)
except NameError as e:
print(e)
It depends on what you want. Within the __init__ method {name} will print the value you passed for that argument. {self.name} will print the instance attribute.
In [10]: d = Dog('foo',1,2)
My name's foo
My name's foo-sss-
In instance methods you need to use self.
In [11]: d.s()
foo-sss-
name 'name' is not defined
Lets assume that I have a class called Person, and a class that inherits this called Group. Person has an attribute called name and one called age. When I create a Group I want to pass n person objects and their new name is a combo of names, and their new age is their combined age.
also for the hell of it, going to keep track of how many people, and how many groups there are separately (just so inheriting makes any sense in this example.)
class Person:
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
self.id = make_person() # count is also the person's id in this example
def __str__(self):
return f'Name: {self.name} Age: {self.age}'
#classmethod
def make_person(cls):
cls.count += 1
return cls.count
class Group(Person):
def __init__(self, *people):
#not sure how to do this, Below Does Not Work, something like
new_name = self.make_group(people)
new_age = self.new_age(people)
self.name = new_name
self.age = new_age
super().__init__(self.new_name, self.new_age)
def make_group(self, *people):
return (' & ').join([person.name for person in People])
def new_age(self, *people):
return sum([person.age for person in people])
then you would think i could write
anne = Person('Anne', 20)
bob = Person('Bob', 20)
carl = person('Carl', 25)
couple = Group(anne, bob)
threesome = Group(anne, bob, carl)
print(couple)
print(threesome)
but this doesnt work. For some reason the group class isnt getting the people object i pass, or i'm defining it wrong...any ideas?
What you have written is that a Group is a particular type of Person. This doesn't seem quite right to me. Regardless, here is a version that will run and give the desired output:
class Person:
count = 0
def __init__(self, name, age):
self.name = name
self.age = age
self.id = Person.make_person() # count is also the person's id in this example
def __str__(self):
return f'Name: {self.name} Age: {self.age}'
#classmethod
def make_person(cls):
cls.count += 1
return cls.count
class Group(Person):
def __init__(self, *people):
#not sure how to do this, Below Does Not Work, something like
new_name = self.make_group(*people)
new_age = self.new_age(*people)
self.name = new_name
self.age = new_age
super().__init__(self.name, self.age)
def make_group(self, *people):
return (' & ').join([person.name for person in people])
def new_age(self, *people):
return sum([person.age for person in people])
anne = Person('Anne', 20)
bob = Person('Bob', 20)
carl = Person('Carl', 25)
couple = Group(anne, bob)
threesome = Group(anne, bob, carl)
print(couple)
print(threesome)
Changes from your code:
some typos with capital letters
put a * before people when passing it
take care of variable scope
I wrote a class called person and used setter and getter. At first, the code was working fine when I used one variable.However when I added another variable , it said that 2 required positional arguments were missing:"name" and "age".
class person:
def __init__(self, name, age):
self.name = name
self.age = age
def set_name(self,y):
self.name = y
def get_name(self):
return self.name
def set_age(self,x):
self.age = x
def get_age(self):
return self.age
p1 = person()
p1.set_name("Armeen")
p1.set_age("20")
print(p1.get_age())
print(p1.get_name())
Your __init__ method takes two arguments namely name and age. You aren't providing any argument when creating an instance of Person. So you may want to do the following:
p1 = person('Armeen', 20)
As opposed to
p1 = person()
Or if you want to allow user not to specify name and age at the time of instance creation, you can set those parameter as optional by doing the following change in __init__
def __init__(self, name = None, age = None): ##This would work with your code as well