在查看dir中列出的属性和方法列表时,您如何知道属性和方法?

时间:2009-05-18 22:42:39

标签: python attributes methods python-datamodel

我正在努力学习使用Python编程,并专注于更好地处理如何使用标准模块和其他模块。 dir函数在解释器中似乎非常强大,但我想知道我是否因为缺少OOP背景而遗漏了某些内容。使用S.Lotts一书,我决定使用他的Die类来学习有关类和实例的语法和用法的更多信息。

以下是原始代码:

class Die(object):
''' simulate a six-sided die '''
def roll(self):
    self.value=random.randrange(1,7)
    return self.value
def getValue(self):
    return self.value

我正在查看它,在创建了一些实例之后,我想知道单词value是否是某个关键字,以及在class语句中使用了word对象,所以我决定通过将类定义更改为以下内容:

class Die():
''' simulate a six-sided die '''
def roll(self):
    self.ban=random.randrange(1,7)
    return self.ban
def getValue(self):
    return self.ban

这一变化向我展示了我从我的实例中获得了相同的行为,但是当我执行dir时,实例中缺少以下方法/属性:

'__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
 '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
_repr__', '__setattr__', '__str__', '__weakref__'

我还想到,当我在一个实例上做了一个目录时,我有一个额外的关键字 - 禁止,我最终想到的是我的实例的一个属性。这有助于我理解我可以使用 d1.ban 来访问我的实例的值。我能弄清楚这是一个属性的唯一原因是我输入了 d1.happy 并得到了 AttributeError 我发现了 d1.GetValue 是一种附在Die上的方法,因为这就是翻译告诉我的。

因此,当我尝试使用像BeautifulSoup这样复杂但有用的模块时,如何在输入 dir(instance)。我需要知道这一点,因为这个问题告诉我,通过属性我调用方法的结果和方法,我在我的实例上调用一个函数。

这个问题可能过于冗长,但确实有助于我更好地理解属性和方法之间的区别。具体来说,当我看到在我的Die类的实例上调用dir的结果时,我看到了这个

['__doc__', '__module__', 'ban', 'getValue', 'roll']

因此,通过查看列表中的属性和方法而不必诉诸试验和错误或者输入 hasattr(myInstance,suspAttributeName)来了解它似乎很有用。 / p>

在发布我试过的问题之后

for each in dir(d1):
    print hasattr(d1,each)

它严格地告诉我所有方法都是属性。但是我不能在没有()的情况下调用方法,所以在我看来hasattr()是误导性的。

6 个答案:

答案 0 :(得分:7)

而不是:“print hasattr(d1,each)”,请尝试:“print each, type(getattr(d1,each))”。你应该找到有用的结果。

此外,代替dir()试试help(),我认为您真的在寻找。

答案 1 :(得分:4)

考虑使用标准库的inspect模块 - 它通常是最自省的内省方法,包含大量功能(您可以从头开始实现,但重用经过良好测试,设计良好的代码是好事)。有关所有详细信息,请参阅http://docs.python.org/library/inspect.html,但例如inspect.getmembers(foo, inspect.ismethod)是获取foo所有方法的绝佳方法(您将按名称排序(name, value)对。)

答案 2 :(得分:2)

  

它严格地告诉我所有方法都是属性。但是我不能在没有()的情况下调用方法,所以在我看来hasattr()是误导性的。

为什么会误导?如果obj.ban()是方法,则obj.ban是相应的属性。您可以使用以下代码:

print obj.getValue()

get = obj.getValue
print get()

如果要获取对象的方法列表,可以尝试此功能。它并不完美,因为它也会触发不是方法的可调用属性,但99%的情况应该足够好:

def methods(obj):
    attrs = (getattr(obj, n) for n in dir(obj))
    return [a for a in attrs if a.hasattr("__call__")]

答案 3 :(得分:2)

这个来自Dive to Python的info模块就是为了达到目的。

def info(obj, spacing=20, collapse=1, variables=False):
    '''Print methods and their doc Strings

    Takes any object'''
    if variables:
    methodList = [method for method in dir(obj)]
    else:
    methodList = [method for method in dir(obj) if callable(getattr(obj,method))]

    #print methodList


    print '\n'.join(['%s %s' %
            (method.ljust(spacing),
             " ".join(str(getattr(obj,method).__doc__).split()))
            for method in methodList])


if __name__=='__main__':
    info(list)

答案 4 :(得分:1)

理想情况下,在使用像BeautifulSoup这样的复杂库时,您应该查阅其文档以了解每个类提供的方法。但是,在极少数情况下,如果您没有易于访问的文档,则可以使用以下方法检查方法是否存在。

所有方法本身都是对象,它们实现__call__方法,并且如果要检查的值具有True方法,则可以使用返回__call__的callable()方法进行检查。

以下代码应该有效。

x = Die()
x.roll()

for attribute in dir(x) :
    print attribute, callable(getattr(x, attribute))

以上代码对所有方法都返回true,对所有非可调用属性(如ban等数据成员)返回false。但是,此方法还为任何可调用对象(如内部类)返回True。您还可以检查属性的类型是否为instancemethod

答案 5 :(得分:1)

有一个名为callable的内置方法。您可以将它应用于任何对象,它将返回True / False,具体取决于是否可以调用它。 e.g。

>>> def foo():
...   print "This is the only function now"
...
>>> localDictionary = dir()
>>> for item in localDictionary:
...   print repr(item) + "is callable: " + str(callable(locals()[item]))
'__builtins__'is callable: False
'__doc__'is callable: False
'__name__'is callable: False
'foo'is callable: True

请注意,locals()调用将返回包含当前范围中定义的所有内容的字典。我这样做是因为字典中的项目只是字符串,我们需要在实际对象上运行callable。