创建python工厂方法

时间:2014-03-21 21:59:47

标签: python factory class-method

我有以下简单示例:

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!"

我正在尝试使用以下内容创建此类的对象:

cat_zoo = CatZoo.make_zoo_cat('squeakers', 12, 'M', 'KC')
print "The name is {}".format(cat_zoo.names)

这只是一个例子,我只是想让我的工厂方法工作(make_zoo_cat,make_zoo_cats)。第一个将传递一个名称,年龄,性别和位置,其中第二个将传递名称,年龄和性别列表以及一个位置。如果我运行此代码,我会得到以下输出:

The name is <property object at 0x7fe313b02838>

谢谢,

2 个答案:

答案 0 :(得分:3)

删除NotImplemented初始化程序并实际创建实例,而不是改变类本身:

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!"

请注意,除了make_zoo_catmake_zoo_cats之间的方法名称之外,没有实际差异,参数名称的差异不会在此处更改功能。

相反,我假设._names应该始终是一个列表,make_zoo_cat(单数)应该创建一个CatZoo,其中包含一个猫的名字。

请记住Python is not Java;你真的不需要所有property个对象,而不是你可以直接访问属性的地方。

答案 1 :(得分:1)

您没有在代码中创建任何对象 在你的make_zoo_cats中你返回cls,所以你仍然有一个类而不是这个类的实例 此代码将打印是

if CatZoo.make_zoo_cat('squeakers', 12, 'M', 'KC') == CatZoo:
    print 'yes'

您同意,但不能这样做,因为将其命名为属性,只有在您拥有该类的实例时才会存在。

CatZoo.names

能够在该类的实例上使用您需要的属性
类似的东西(这将在你的代码中引发):

cat = CatZoo()
cat.names  # I can do this now

你的make_zoo_cat中另一个你创建类变量的点,这些变量可以从类中访问(不需要在该类上有一个实例)但是#34; common&#34;对所有人来说。

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

结果将是这样的:

squeakers
12
M
KC
**********
squeakers
12
M
KC
**********
other
42
F
FR
**********
other
42
F
FR
**********
other
42
F
FR

前两个给我相同的结果,最后三个也是,这是因为它们是类变量,你总是有相同的类,所以修改其中一个变量会影响另一个