let's say i got some pickled data in an class structure like the following:
class dog:
def __init__(self, nameDog, age):
self.nameDog = namedog
self.age = age
self.favoriteToys = {}
class toy:
def __init__(self, nameToy):
self.nameToy = nameToy
self.color = ''
Now i want to load the data an use it in an new structure with an extra Attribute based on the old structure.
class dog:
def __init__(self, nameDog, age):
self.nameDog = namedog
self.age = age
self.breed = ''
self.favoriteToys = {}
class toy:
def __init__(self, nameToy):
self.nameToy = nameToy
self.color = ''
Is there an easy way to do it?
You might want to create a class that is derived from another. That is called inheritance Python inheritance.
class Rottweiler(dog):
def __init__(self, nameDog, age):
super().__init__(nameDog, age)
self.breed = ''
Using the super() function, your child class (Rottweiler) will automatically inherit the methods and properties from its parent (dog).
Related
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 am new to OOP. My idea was to implement the following class:
class name(object, name):
def __init__(self, name):
print name
Then the idea was to create two instances of that class:
person1 = name("jean")
person2 = name("dean")
I know, that is not possible, but how can I pass an input-argument into an instance of a class?
The problem in your initial definition of the class is that you've written:
class name(object, name):
This means that the class inherits the base class called "object", and the base class called "name". However, there is no base class called "name", so it fails. Instead, all you need to do is have the variable in the special init method, which will mean that the class takes it as a variable.
class name(object):
def __init__(self, name):
print name
If you wanted to use the variable in other methods that you define within the class, you can assign name to self.name, and use that in any other method in the class without needing to pass it to the method.
For example:
class name(object):
def __init__(self, name):
self.name = name
def PrintName(self):
print self.name
a = name('bob')
a.PrintName()
bob
>>> class name(object):
... def __init__(self, name):
... self.name = name
...
>>> person1 = name("jean")
>>> person2 = name("dean")
>>> person1.name
'jean'
>>> person2.name
'dean'
>>>
You just need to do it in correct syntax. Let me give you a minimal example I just did with Python interactive shell:
>>> class MyNameClass():
... def __init__(self, myname):
... print myname
...
>>> p1 = MyNameClass('John')
John
Remove the name param from the class declaration. The init method is used to pass arguments to a class at creation.
class Person(object):
def __init__(self, name):
self.name = name
me = Person("TheLazyScripter")
print me.name
Actually you can!
How about this?
class name(str):
def __init__(self, name):
print (name)
# ------
person1 = name("jean")
person2 = name("dean")
print('===')
print(person1)
print(person2)
Output:
jean
dean
===
jean
dean
Python Classes
class name:
def __init__(self, name):
self.name = name
print("name: "+name)
Somewhere else:
john = name("john")
Output:
name: john
class Person:
def init(self,name,age,weight,sex,mob_no,place):
self.name = str(name)
self.age = int(age)
self.weight = int(weight)
self.sex = str(sex)
self.mob_no = int(mob_no)
self.place = str(place)
Creating an instance to class Person
p1 = Person(Muthuswamy,50,70,Male,94*****23,India)
print(p1.name)
print(p1.place)
Output
Muthuswamy
India
I want to build a class which is basically an array of objects. I want this class to return me a list of attributes of its members. For example, from the class :
class Animal():
def __init__(self, height, age):
self.height = height
self.age = age
dog = Animal(1,2)
cat = Animal(3,4)
I want to create a class Group which would do:
my_group = Group([dog,cat])
print(my_group.height) #return [1,3] or (1,3) or array([1,3])
I have thought of doing:
import inspect
def get_attribute(instance):
"""Return all attributes of an instance (except all internal built-in)"""
attributes = inspect.getmembers(instance, lambda a:not(inspect.isroutine(a)))
return [a for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))]
class Group():
def __init__(self, members):
self.members = members
attributes = [a[0] for a in get_attribute(list(members)[0])] #assuming members are all of the same class
for a in attributes:
setattr(self, a, [getattr(m, a) for m in self.members])
I can then use Group for others classes, for example:
class Human():
def __init__(self, name, weight):
self.name = name
self.weight = weight
class Family(Group):
pass
alan = Human("alan", 1)
bob = Human("bob", 2)
my_family = Family([alan, bob])
print(my_family.weight) #returns [1, 2]
This works but seems inefficient if the number of members gets very high since it loops over each members. Basically, my code works but I would like to make it faster using functions like map or something similar.
use a class attribute:
class Animal():
all_data = {"height":[],"age":[]}
def __init__(self, height, age):
self.height = height
self.age = age
Animal.all_data["age"].append(age)
Animal.all_data["height"].append(height)
dog = Animal(1,2)
cat = Animal(3,4)
print(Animal.all_data["height"])
print(Animal.all_data["age"])
Perhaps you can just define a method to keep it dynamic:
class Animal():
def __init__(self, height, age):
self.height = height
self.age = age
dog = Animal(1,2)
cat = Animal(3,4)
class Group():
def __init__(self, members):
self.members = members
def get_all_attr(self, a):
return [getattr(m,a) for m in self.members]
my_group = Group([dog,cat])
print(my_group.get_all_attr("height")) #returns [1,3]
I don't think you can get away without looping over the members every time unless you use lazy initialization.
I have a class Participant as follows:
class Participant:
def __init__(self,name,level):
self.name = name
self.level =level
I also have another class Team as follows:
class Team:
def __init__(self,name):
self.name = name
I want to create a method in the class Team to add an instance of class Participant; for instance:
Assume myTeam is an empty, valid instance of Team.
Also assume myParticipant1 is a valid instances of Participant
myTeam.addParticipant(participant= myParticipant1)
AddParticipant method should add the instance myParticipant1 to the instance myTeam.
How do I acheive it in Python?
Aside from the inheritance questions we're talking about in the comments, this is pretty simple stuff.
class Participant(object):
def __init__(self, name, level):
self.name = name
self.level = level
class Team(object):
def __init__(self, name):
self.name = name
self.participants = []
def add_participant(p):
self.participants.append(p)
DEMO:
my_team = Team("Monty Python")
p_info = [("Adam", 10e5), ("Joe-bob", -1)]
participants = [Participant(name, level) for name, level in p_info]
for participant in participants:
my_team.add_participant(participant)
# say that 10 times fast....
In [1]: [p.name for p in my_team.participants]
Out[1]: ["Adam", "Joe-bob"]
Say I have a pair of instances that reference one another mutually. Is there a preferable manner to structure this relationship than the following.
class Human():
def __init__(self, name):
self.name = name
self.pet = Dog('Sparky', self)
def pet(self, animal):
self.pet.receive_petting()
class Dog(Pet):
def __init__(self, name, owner):
self.name = name
self.owner = owner
def receive_petting(self):
pass
def bark_at(self, person):
"do something"
The thing I don't like is that the relationship needs to be specified in two places. Any ideas on how to make this dryer?
I would break this into three classes:
class Human():
def __init__(self, name):
self.name = name
class Dog(Pet):
def __init__(self, name):
self.name = name
def bark_at(self, person):
"do something"
class OwnerPetRelation():
def __init__(self, dog, human):
self.owner=human
self.pet=dog
Now, one owner can also have many dogs, we just need to define as many OwnerPetRelations.
Similarly, a dog can also belong to multiple owners now.
I would create a method on Human that allows you to add pets (since a human might have many pets):
class Human():
def __init__(self, name):
self.name = name
self.pets = []
def add_pet(self, pet):
pet.owner = self
self.pets.append(pet)
def pet(self, animal):
for pet in self.pets:
pet.receive_petting()
class Dog(Pet):
def __init__(self, name):
self.name = name
self.owner = None
def receive_petting(self):
pass
def bark_at(self, person):
"do something"
This can be used as follows
human = Human('Jim')
human.add_pet(Dog('Woof'))
This approach can of course also be used for just a single pet and one could also extend it to allow pets to be owned by many humans.
There's nothing really Python-specific here; this is just a limitation of constructor-based dependency injection. It's hard to inject a reference to another object that cannot have been created yet. Instead, you can create an object that has a reference to something that will have a reference to the other object. For instance, you can pass a function to the constructor that will be able to return the value:
class Human():
def __init__(self,name,dog):
self.name = name
self._dog = dog
#property
def dog(self):
return self._dog()
class Dog():
def __init__(self,name,human):
self.name = name
self._human = human
#property
def human(self):
return self._human()
Then you can use it like this:
human = None
dog = Dog('fido',lambda: human)
human = Human('john',lambda: dog)
print(dog.human.name)
print(human.dog.name)
john
fido
It is not hard to update this so that the property function caches the value, of course. E.g.:
class Dog():
def __init__(self,name,human):
self.name = name
self._human = human
#property
def human(self):
try:
return self._human_
except AttributeError:
self._human_ = self._human()
return self._human_