代码之家  ›  专栏  ›  技术社区  ›  Pau

使字符串成为实例/对象的名称

  •  0
  • Pau  · 技术社区  · 16 年前

    我已经挣扎了好几天了…

    我试图找到一种方法来实例化一些对象,我可以通过一个原始的输入调用命名这些对象,然后,当我需要时,通过'print variable name'命令和 STR ()方法。

    举个例子。假设我想建立一个有10只动物的动物园…

        class Zoo(object): 
            def __init__(self, species, legs, stomachs):
                self.species = species
                self.legs = legs
                self.stomachs = stomachs
    
    
    for i in range(9): 
        species = raw_input("Enter species name: ")
        legs = input("How many legs does this species have? ")
        stomachs = input("...and how many stomachs? ")
        species = Zoo(species, legs, stomachs)
    

    其思想是“species”变量(for循环的第一行)例如species=bear成为对象“bear”(循环的最后一行),它与 STR 方法和“print bear”命令将为我提供bears属性。

    就像我说的,我已经挣扎了一段时间了,但是尽管看了其他类似主题的帖子,仍然找不到办法。有人说使用字典,也有人说使用setattr(),但在我的示例中看不到这是如何工作的。

    5 回复  |  直到 16 年前
        1
  •  6
  •   rcoder    16 年前

    如果只想在模块命名空间中引入新的命名变量,那么 setattr 可能是最简单的方法:

    import sys
    
    class Species:
        def __init__(self, name, legs, stomachs):
            self.name = name
            self.legs = legs
            self.stomachs = stomachs
    
    def create_species():
        name = raw_input('Enter species name: ')
        legs = input('How many legs? ')
        stomachs = input('How many stomachs? ')
        species = Species(name, legs, stomachs)
        setattr(sys.modules[Species.__module__], name, species)
    
    if __name__ == '__main__':
        for i in range(5):
            create_species()
    

    如果将此代码保存到名为 zoo.py ,然后从另一个模块导入,可以按如下方式使用:

    import zoo
    zoo.create_species() # => enter "Bear" as species name when prompted
    animal = zoo.Bear # <= this object will be an instance of the Species class
    

    不过,一般来说,使用字典是维护命名值集合的一种更为“蟒蛇式”的方法。动态绑定新变量有很多问题,包括大多数人希望模块变量在程序运行期间保持相当稳定。此外,python变量的命名规则比可能的一组动物名要严格得多——例如,不能在变量名中包含空格, 塞特拉特 会很高兴地存储价值,你必须使用 getattr 去找回它。

        2
  •  1
  •   Alex Martelli    16 年前

    这真的,真的,真的是一个很糟糕的主意,在运行中创建不命名的变量- 诚挚地 恳求你放弃这个要求 print FOOBAR 对于一个从未存在于法典中的无名美食家,就像我恳求一个渴望自杀的人类同胞放弃他们疯狂的欲望,给生命一个机会一样。使用字典,使用 'FOOBAR' 作为论据和调查等。

    但如果我的人类同胞坚定地希望结束他们的生活,我可能会转而建议如何在对自己和他人造成最小附带损害的情况下做到这一点。相当于…:

    class Zoo(object): 
        def __init__(self, species, legs, stomachs):
            self.species = species
            self.legs = legs
            self.stomachs = stomachs
            import __builtin__
            setattr(__builtin__, species, self)
    

    通过显式使用 __builtin__ 模块,确保可以从任何模块“打印speciesname”—而不仅仅是定义 Zoo ,也不只是实例化它的那个。

    这仍然是一个可怕的想法,但这是实现它最不可怕的方法。

        4
  •  0
  •   Jochen Ritzel    16 年前
    class Zoo(object):
        def __init__(self, name):
            self.name = name
            self.animals = []
    
        def __str__(self):
            return ("The %s Zoo houses:\n" % self.name) + "\n".join(str(an) for an in self.animals)
    
    class Animal( object ):
        species = None
        def __init__(self, legs, stomach):
            self.legs = legs
            self.stomach = stomach
    
        def __str__(self):
            return "A %s with %d legs and %d stomachs" % ( self.species, self.legs, self.stomach )
    
    
    class Bear( Animal ):
        species = "Bear"
    
    class Karp( Animal ):
        species = "Karp"
    
    
    ## this is the point ... you can look up Classes by their names here
    ## if you wonder show to automate the generation of this dict ... don't.
    ## ( or learn a lot Python, then add a metaclass to Animal ;-p )
    species = dict( bear = Bear,
                    karp = Karp )
    
    zoo = Zoo( "Strange" )
    while len(zoo.animals) < 9:
        name = raw_input("Enter species name: ").lower()
        if name in species:
            legs = input("How many legs does this species have? ")
            stomachs = input("...and how many stomachs? ")
            zoo.animals.append( species[name]( legs, stomachs ) )
        else:
            print "I have no idea what a", name, "is."
            print "Try again" 
    
    print zoo
    
        5
  •  0
  •   Tzury Bar Yochay    16 年前
    >>> class Bear():
    ...     pass
    ... 
    >>> class Dog():
    ...     pass
    ... 
    >>> 
    >>> types = {'bear': Bear, 'dog': Dog}
    >>> 
    >>> types['dog']()
    <__main__.Dog instance at 0x75c10>