Reputation: 2148
I have the following simple example:
class CatZoo(object):
def __init__(self):
raise NotImplemented
@classmethod
def make_zoo_cat(cls, name, age, gender, location):
cls._names = name
cls._ages = age
cls._genders = gender
cls._location = location
return cls
@classmethod
def make_zoo_cats(cls, names, ages, genders, location):
cls._names = names
cls._ages = ages
cls._genders = genders
cls._location = location
return cls
@property
def location(self):
return self._location
@property
def names(self):
return self._names
def age(self, name):
if name in self._names:
return self._ages[self._names.index(name)]
else:
return None
def gender(self, name):
if name in self._names:
return self._genders[self._names.index(name)]
else:
return None
@property
def meow(self):
return "meow!"
And I am trying to create an object of this class by using the following:
cat_zoo = CatZoo.make_zoo_cat('squeakers', 12, 'M', 'KC')
print "The name is {}".format(cat_zoo.names)
This is just an example, I am just trying to make my factory methods work (make_zoo_cat, make_zoo_cats). The first will be passed one name, age, gender and location where the second would be passed a list of names, ages and genders and one location. If I run this code, I get the following output:
The name is <property object at 0x7fe313b02838>
Thanks,
Upvotes: 1
Views: 354
Reputation: 818
You didn't create any object in your code.
In your make_zoo_cats you return cls, so you still have a class not an instance of this class.
This code will print the yes
if CatZoo.make_zoo_cat('squeakers', 12, 'M', 'KC') == CatZoo:
print 'yes'
You agree than you can't do that, since name its a property it will only exist if you have an instance of that class.
CatZoo.names
to be able to use the property you need on instance of that class
something like that (this will raise in your code):
cat = CatZoo()
cat.names # I can do this now
An other point in your make_zoo_cat you create Class variables, those variables are accessible from the class (no need to have an instance on that class) but are "common" to all.
c1 = CatZoo.make_zoo_cat('squeakers', 12, 'M', 'KC')
print c1._names
print c1._ages
print c1._genders
print c1._location
print '*'*10
print CatZoo._names
print CatZoo._ages
print CatZoo._genders
print CatZoo._location
print '*'*10
c2 = CatZoo.make_zoo_cat('other', 42, 'F', 'FR')
print c2._names
print c2._ages
print c2._genders
print c2._location
print '*'*10
print CatZoo._names
print CatZoo._ages
print CatZoo._genders
print CatZoo._location
print '*'*10
print c1._names
print c1._ages
print c1._genders
print c1._location
the result will be someting like that:
squeakers 12 M KC ********** squeakers 12 M KC ********** other 42 F FR ********** other 42 F FR ********** other 42 F FR
The first two give me the same result, and the last three as well, this is because they are class variables and you always have the same class so modifying one of those variable will affect the other
Upvotes: 1
Reputation: 1121534
Remove the NotImplemented
initializer and actually create instances of your class, instead of mutating the class itself:
class CatZoo(object):
def __init__(self, name, age, gender, location):
self._names = name
self._ages = age
self._genders = gender
self._location = location
@classmethod
def make_zoo_cat(cls, name, ages, genders, location):
return cls.mak_zoo_cats([name], age, gender, location)
@classmethod
def make_zoo_cats(cls, names, ages, genders, location):
return CatZoo(names, age, gender, location)
@property
def location(self):
return self._location
@property
def names(self):
return self._names
def age(self, name):
if name in self._names:
return self._ages[self._names.index(name)]
else:
return None
def gender(self, name):
if name in self._names:
return self._genders[self._names.index(name)]
else:
return None
@property
def meow(self):
return "meow!"
Note that there was no real difference other than the method name between make_zoo_cat
and make_zoo_cats
, the difference in argument names doesn't change the functionality here.
Instead, I presumed that ._names
should always be a list and that make_zoo_cat
(singular) should create a CatZoo
with one cat name in it.
Just remember that Python is not Java; you really don't need all those property
objects, not where you could just access the attribute directly.
Upvotes: 3