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

StackOverflow https://stackoverflow.com/questions/880160

我正在努力尝试在Python进行编程,并专注于更好地处理如何使用标准和其他模块。 DIR功能在解释器中似乎真的很强大,但是我想知道由于缺乏OOP背景,我是否缺少某些东西。我决定使用S.Lotts书籍,决定使用他的模具班来了解有关语法以及类和实例的使用。

这是原始代码:

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

我正在看这件事,在创建了一些实例之后,我想知道“值”一词是否是关键字,并且在类语句中对“对象”一词的使用做了什么,因此我决定通过将类定义更改为以下内容来找出答案:

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__'

我还发现,当我在一个实例上做一个dir时,我有一个其他关键字 -禁止 我终于发现的是我实例的属性。这帮助我了解我可以使用 d1.ban 访问我实例的价值。我能弄清楚这是一个属性的唯一原因是我输入了 D1 并得到了 属性 我发现 d1.getValue 是一种死亡的方法,因为那是口译员告诉我的。

因此,当我尝试使用一些复杂但有用的模块时,例如Beautifulsoup,我如何知道列出的哪些内容是我实例或实例方法的属性 dir(实例). 。我需要知道这一点,因为这种戳戳告诉我,有了属性,我称之为方法的结果,并且通过方法,我正在调用我的实例函数。

这个问题可能太言语了,但确实可以帮助我更好地理解属性和方法之间的区别。具体来说,当我查看在我的模具类实例上致电dir的结果时,我会看到这个

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

因此,通过查看该列表是属性,哪些是方法,而无需诉诸于反复试验或输入的结果似乎很有用 hasattr(myinstance,可疑attributename).

发布问题后,我尝试了

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

严格来说,这告诉我所有方法都是属性。但是没有 () 在我看来,hasattr()具有误导性。

有帮助吗?

解决方案

代替: ”print hasattr(d1,each)“, 尝试: ”print each, type(getattr(d1,each))“。您应该找到结果信息。

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

其他提示

考虑使用标准库的 inspect 模块 - 通常是内省的最方便方法,包装了大量功能(您可以从头开始实现,但是重复测试,经过良好设计的代码是一件好事)。看 http://docs.python.org/library/inspect.html 为了所有细节,例如 inspect.getmembers(foo, inspect.ismethod) 是获取所有Foo方法的绝佳方法(您会得到 (name, value) 对按名称排序)。

严格来说,这告诉我所有方法都是属性。但是我不能没有(),所以在我看来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__")]

这个 info 从潜水中启发到Python的模块实现了目的。

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)

有一个内置的方法称为Callable。您可以将其应用于任何对象,它将根据是否可以调用true/false返回。例如

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

注意当地人()调用将返回一个字典,其中包含当前范围中定义的所有内容。我之所以这样做,是因为字典中的项目只是字符串,我们需要在实际对象上运行可召唤。

理想情况下,当使用像Beautifulsoup这样的复杂库时,您应该咨询其文档,以查看每个班级提供的方法。但是,在极少数情况下,您没有容易访问的文档,可以使用以下内容检查是否存在方法。

所有方法本身就是对象,都可以实现 __call__ 方法,可以使用返回的callable()方法检查 True, ,如果被检查的值 __call__ 方法。

以下代码应起作用。

x = Die()
x.roll()

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

上面的代码将返回所有方法的true,对于所有非可呼叫属性(例如BAN等数据成员)的false。但是,此方法也返回 True 对于任何可呼叫的对象(例如内部类)。您还可以检查属性的类型是否为 instancemethod

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top