whenever i print the c1 object, it prints:
<main.Car object at 0x7fde8b29a240>
however i added the str method, to format it to a proper string, why is it not printing a readable string?
import copy
class Prototype:
def __init__(self):
# constructor method to create the object
self._objects = {}
def register_object(self, name, obj):
# this method is used to register an object
self._objects[name] = obj
def unregister_object(self, name):
# this method is used to unregister an object
del self._objects[name]
def clone(self, name, **attr):
obj = copy.deepcopy(self._objects.get(name))
obj.__dict__.update(attr)
return obj
class Car:
def __init__(self):
self.name = "Skylark"
self.color = "blue"
self.options = "extra horsepower in engine"
def __str__(self):
return '{} | {} | {}'.format(self.name, self.color, self.options)
c = Car()
prototype = Prototype()
prototype.register_object('skylark',c)
c1 = prototype.clone('skylark')
print(c1)
There is a problem with the indentation in your code. I've corrected this and can get the desired answer too. The indentation is a bit off for the function defs. in both the classes.
I've called this file as test.py
import copy
class Prototype:
def __init__(self):
# constructor method to create the object
self._objects = {}
def register_object(self, name, obj):
# this method is used to register an object
self._objects[name] = obj
def unregister_object(self, name):
# this method is used to unregister an object
del self._objects[name]
def clone(self, name, **attr):
obj = copy.deepcopy(self._objects.get(name))
obj.__dict__.update(attr)
return obj
class Car:
def __init__(self):
self.name = "Skylark"
self.color = "blue"
self.options = "extra horsepower in engine"
def __str__(self):
return '{} | {} | {}'.format(self.name, self.color, self.options)
c = Car()
prototype = Prototype()
prototype.register_object('skylark',c)
c1 = prototype.clone('skylark')
print(c1)
When I run the file
$ python test.py
The output is:
#Output: Skylark | blue | extra horsepower in engine
Related
I have a list of objects of the Person class. This list includes myself, so I need to remove "myself" from the list.
It means I need to remove the object from the list that calls this method.
class Population:
def __init__(self):
self.people = list()
class Person:
def __init__(self):
self.friends_list = list()
def make_friends(self, population, n):
temp_list = population.copy()
temp_list.remove(self)
self.friends_list.extend(random.sample(temp_list,n))
my test:
per = Person()
per2 = Person()
per3 = Person()
per4 = Person()
per5 = Person()
pop = [per,per2,per3,per4,per5]
for per in pop:
per.make_friends(pop, 2)
print('ME: ',per)
print(per.friends_list)
My tests run well, but there are general tests that check the code and they generate an error on this line:
try:
stud_res = person.make_friends(population, count)
except Exception:
print("\tPerson.make_friends() generated error")
return
Can I use self in this way, and if not, how can I better remove "myself" from the list?
It is a perfectly fine use case. By the way, note that you're overriding the builtin list.
To use self, you have to share a list collection between instances of a Person-class. In that case this collection should be declared as a class attribute or global list variable (not an instance attribute).
These samples of code are working:
with global list variable:
class Person:
def __init__(self, name):
self.name = name
def make_friends(self, list):
list.remove(self)
def __repr__(self):
return self.name
p1 = Person("Joe")
p2 = Person("Barack")
the_list = []
the_list.append(p1)
the_list.append(p2)
p1.make_friends(the_list)
print(the_list)
With class attribute:
class Person2:
class_list = []
def __init__(self, name):
self.name = name
Person2.class_list.append(self)
def make_friends(self):
Person2.class_list.remove(self)
def __repr__(self):
return self.name
p1 = Person2("Joe")
p2 = Person2("Barack")
print(Person2.class_list)
p1.make_friends()
print(Person2.class_list)
EDIT:
Variable 3 when a list of people is inside another class.
For accessing a list inside another class you could use attribute name or public method to get it if implemented:
class ClassWithList:
def __init__(self):
self.list_collection = []
def get_list(self):
return self.list_collection
class_with_list = ClassWithList()
class Person:
def __init__(self, name):
self.name = name
def make_friends(self, list):
list.remove(self)
def __repr__(self):
return self.name
p1 = Person("Joe")
p2 = Person("Barack")
# using implemented get-method of instance list attribute
class_with_list.get_list().append(p1)
class_with_list.get_list().append(p2)
print(class_with_list.get_list())
p1.make_friends(class_with_list.get_list())
print(class_with_list.get_list())
# instance list attribute of class`ClassWithList
print(class_with_list.list_collection)
p2.make_friends(class_with_list.list_collection)
print(class_with_list.list_collection)
I am new to structure Python projects, so please forgive any wrong approaches that could be written down here.
Two JSON schemes represent two objects. These are serialised into classes and have properties in common.
Example:
class TwoWheelVeicle(object):
def __init__(self,v_family, v_subfamily):
self.Family = v_family
self.SubFamily = v_subfamily
self.OtherProp = "other"
class FourWheelVeicle(object):
def __init__(self,v_family):
self.Family = v_family
self.AnotherProp = "another"
def run_an_highway(vehicle):
if isinstance(vehicle,FourWheelVeicle):
return "Wrooom"
if isinstance(vehicle,TwoWheelVeicle):
if veichle.SubFamily in SubFams.NotAllowed:
return "ALT!"
else:
return "Brooom" #forgive me for the sound
class SubFams(object):
NotAllowed = ["Bicycle","50cc"]
Known = ["200cc","Motorbike"]
I am quite unsure of the procedure overall:
- Shall I create an abstract parent class?
- Is NotAllowed stored correctly? This is due to the need of changing its content (that is serialized from some global parameter JSON, it's a #TODO)
..or simply I should not want to do any of these?
Lastly, the code does not allow for any checks if the properties that I serialize are correct (what if SubFamily is unknown? Should it be checked in the decoder?).
A big thank you.
Looks like you should abstract vehicle with a Vehicle class and then subclass it for your different vehicle types.
Your if chain isn't needed if your different subclasses have their own version for that same method.
Something in the line with these:
class Vehicle(object):
def __init__(self, name, cc):
self.name = name
self.cc = cc
self.wheels = None
def runs_on_highway(self):
return self.cc > 50
def sound(self):
pass
class TwoWheels(Vehicle):
def __init__(self, name, cc):
Vehicle.__init__(self, name, cc)
self.wheels = 2
def sound(self):
return 'Brooom.'
class FourWheels(Vehicle):
def __init__(self, name, cc):
Vehicle.__init__(self, name, cc)
self.wheels = 4
def sound(self):
return 'Vruuum'
class ElectricWheels(Vehicle):
def __init__(self, name, cc):
Vehicle.__init__(self, name, 0)
self.wheels = 4
def runs_on_highway(self):
return True
def sound(self):
return 'zzzzz.'
v1 = TwoWheels('Bicycle', 50)
v2 = FourWheels('Motorbike', 200)
v3 = ElectricWheels('ElectricBike', 0)
print(v1.runs_on_highway())
print(v2.runs_on_highway())
print(v3.runs_on_highway())
print(v1.name, v1.cc, v1.wheels, v1.sound())
print(v2.name, v2.cc, v2.wheels, v2.sound())
print(v3.name, v3.cc, v3.wheels, v3.sound())
I'm new to python, and I'm having a problem getting this little bit of code to work. I keep running into this same issue. When I run this I get the error message:
TypeError: object() takes no parameters.
I've included the error message in full below.
Here's my code:
class Bird:
_type = ""
def bird(self, type):
self._type = type
def display(self):
print(self._type)
class Species:
_bird = None
_type = ""
def set_bird(self, bird):
self._bird = bird
def display(self):
print(self._type)
self._bird.display(self)
class Cardinal(Species):
def cardinal(self):
self._type = "Cardinal"
def main():
species = Cardinal()
species.set_bird(Bird("Red"))
species.display()
main()
In your code, you are doing:
species.set_bird(Bird("Red"))
While creating the object of Bird, you are passing argument "Red". But there is no __init__() function in Bird class to accept this argument. Your Bird class should be like:
class Bird:
# _type = "" <--- Not needed
# Probably you miss understood it with the
# part needed in `__init__()`
def __init__(self, type):
self._type = type
def bird(self, type):
self._type = type
def display(self):
print(self._type)
You do not have __init__() function inside your Bird class, so you can not write:
Bird("Red")
If you want to pass an argument like that, you need to do:
class Bird:
def __init__(self, color):
self.color = color
# The rest of your code here
Below, you can see the result:
>>> class Bird:
... def __init__(self, color):
... self.color = color
...
>>>
>>>
>>> b = Bird('Red')
>>> b.color
'Red'
I am trying to model services and I am having some issue. What I am trying to do is I would want something such as this in code:
>>> service = Service()
>>> service.name = "Instance1"
>>> service.name.color = "red"
>>> service.name.color.enabled = True
I have tried nesting the Classes but I am still having issues.
Is this completely against convention. If so I will reevaluate and find another way to do so.
EDIT:
I decided to do something like the following by just nesting the classes to copy the Hierarchy.
class Service(object):
_prefix = 'Service'
def __init__(self):
self.name = Service.Name()
class Name(object):
_prefix = 'Service'
def __init__(self):
self.color = Service.Name.Color()
class Color(object):
_prefix = 'Service'
def __init__(self, color="N/A"):
self.color = color
It's not against convention to have other objects as values of attributes of your class.
The best thing you can do it declare your desired classes - in your example these would be class Color, which would have a boolean attribute enabled.
I'd avoid having nested classes, for example:
class Color:
def __init__(self, name, enabled=False):
self.name = name
self.enabled = enabled
def __str__(self):
return self.name
class Service:
def __init__(self, name):
self.name = name
self.palette = None
class Palette:
def __init__(self):
self.colors = []
def __str__(self):
return ' - '.join([str(c) for c in self.colors])
if __name__ == "__main__":
num_services = 8
num_colors = 256
offset = num_colors / num_services
palettes = [Palette() for i in range(num_services)]
services = [Service("Service" + str(i)) for i in range(num_services)]
colors = [Color("color" + str(i)) for i in range(num_colors)]
for i in range(num_services):
subcolors = colors[i * offset:(i + 1) * offset]
palettes[i].colors = subcolors
services[i].palette = palettes[i]
print "Palette {0} -> {1}\n".format(i, palettes[i])
Although I'm not sure what's the meaning of enabling a color in this context
If you mean nested instances, you just create them in the relevant __init__ code (or subsequently)
>>> class LR( object):
... def __init__(self, L=None, R=None):
... self.left = L
... self.right = R
>>> class Thing(object):
... def __init__(self):
... self.tree2=LR( LR(1,2), LR(3,4) )
>>> t = Thing()
>>> t.tree2.left.right
2
In this context, Python modules collections.namedtuple and attrs may be of use. (attrs is quite awesome: https://attrs.readthedocs.io/en/stable/).
If you mean some rather deeper magic like Django's nested Meta classes, then the source code is available. (It's clear enough how to use Django, but I can't say I understand the ins and outs of the nested Meta declaration well enough to do anything similar from scratch in my own code).
Class Person( models.Model)
name = models.CharField( max_length = 100)
... # more field declarations
Class Meta:
unique_together = (("name", "birthdate"),)
.... # more Meta-declarations
You should be looking at composition, not nested classes.
class Color:
def __init__(self, name):
self.name = name
class Service:
def __init__(self, color_obj):
self.color_obj = color_obj
service = Service(Color("yellow"))
print(service.color_obj.name)
>> "yellow"
I have some classes:
class Window(object):
def __init__(self, name):
self.wind_name = name
def getWindowName(self):
return 'wnd' + self.wind_name
class Control(object):
def __init__(self, name, wnd):
self.contrl_name = name
setattr(self, 'getWindowName', wnd.getWindowName)
setattr(self, 'wind_name', wnd.wind_name)
def getControlName(self):
return (self.getWindowName(), 'unk' + self.contrl_name)
class Button(Control):
def __init__(self, name, wnd):
super(Button, self).__init__(name, wnd)
def getControlName(self):
return (self.getWindowName(), 'btn' + self.contrl_name)
wnd = Window('MyApp')
btnOK = Button('OK', wnd)
btnOK.getControlName() # work ok., return ('wndMyApp', 'btnOK')
btnOK.wind_name = 'NewApp'
btnOK.getControlName() # does not work properly., return ('wndMyApp', 'btnOK')
How can I extend the class Control|Button from the object of class Window to access the functions getWindowName and field wind_name in objects btnOK?
Is there a way without creating a field self.wnd = wnd in class Control, or add method setWindowName in Window...?
I can not inherit class Control from the class Window! This is not logical.
Python allows inheriting from multiple classes, i.e.
class Button(Control, Window):
...
But in this case you should know exactly what you are doing (speaking of Pythons Method Resolution Order (MRO)). I'd recommend reading this small book: Python Attributes and Methods.
You can use property for attributes
class Window(object):
def __init__(self, name):
self.wind_name = name
def getWindowName(self):
return 'wnd' + self.wind_name
class Control(object):
def __init__(self, name, wnd):
self.contrl_name = name
self.wnd = wnd
setattr(self, 'getWindowName', wnd.getWindowName)
def get_wind_name(self):
return self.wnd.wind_name
def set_wind_name(self, v):
self.wnd.wind_name = v
wind_name = property(get_wind_name, set_wind_name)
def getControlName(self):
return (self.getWindowName(), 'unk' + self.contrl_name)
class Button(Control):
def __init__(self, name, wnd):
super(Button, self).__init__(name, wnd)
def getControlName(self):
return (self.getWindowName(), 'btn' + self.contrl_name)
wnd = Window('MyApp')
btnOK = Button('OK', wnd)
print btnOK.getControlName() # work ok., return ('wndMyApp', 'btnOK')
btnOK.wind_name = 'NewApp'
print btnOK.getControlName()