Como você sabe quando se olha a lista de atributos e métodos listado em um diretório que são atributos e quais são os métodos?

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

Pergunta

Eu estou trabalhando através tentando aprender a programar em Python e estou focado em conseguir um melhor controle sobre como usar o Padrão e outros módulos.A função dir parece realmente poderoso no intérprete, mas eu me pergunto se eu estou faltando alguma coisa por causa da minha falta de OOP plano de fundo.Utilizando S. Lotts livro eu decidi usar o seu Morrer de classe para saber mais sobre a sintaxe e o uso de classes e instâncias.

Aqui está o código original:

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

Eu estava olhando para isso e, depois de criar alguns casos, gostaria de saber se o valor da palavra, foi uma palavra-chave, de alguma forma, e que o uso da palavra objecto, na classe de instrução fiz, e então eu decidi descobrir por alterar a definição de classe para o seguinte:

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

Essa mudança mostrou-me que eu tenho o mesmo comportamento de minhas instâncias, mas os seguintes métodos/atributos estavam ausentes das instâncias quando eu fiz dir:

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

Eu também descobri que quando eu fiz um comando dir em um exemplo, eu tinha uma palavra-chave adicional-proibição que eu finalmente descobri foi um atributo do meu exemplo.Isso me ajudou a entender que eu poderia usar d1.proibição para acessar o valor da minha instância.A única razão que eu pudesse descobrir que este era um atributo foi digitado d1.feliz e tenho um AttributeError Eu descobri que d1.GetValue era um método conectado para Morrer, porque é essa que o intérprete me disse.

Então, quando eu estou tentando usar alguns complicado, mas é útil módulo como BeautifulSoup como posso saber que as coisas que estão listados são atributos do meu instância ou métodos de meu instância depois de escrever dir(exemplo).Eu preciso saber, porque isto bisbilhotando me ensinou que, com atributos que eu estou chamando o resultado de um método e com métodos estou a invocação de uma função no meu exemplo.

Esta questão é, provavelmente, demasiado prolixo, mas de certeza que me ajudou a entender melhor a diferença entre os atributos e métodos.Especificamente, quando eu olhar para o resultado da chamada dir em uma instância de meu Morrer classe eu vejo isso

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

Assim parece útil para saber por que olhando a lista de quais são os atributos e quais são seus métodos, sem ter que recorrer a tentativa e erro ou resultado para digitar hasattr(myInstance,suspectedAttributeName).

Depois de postar a pergunta que eu tentei

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

que me diz rigorosamente falando que todos os métodos são atributos.mas eu não posso chamar um método sem o () então, parece-me que o hasattr() é enganosa.

Foi útil?

Solução

Ao invés de: "print hasattr(d1,each)", tentar: "print each, type(getattr(d1,each))"Você deve encontrar os resultados informativos.

Além disso, no lugar de dir() tentar help(), o que eu acho que você está realmente procurando.

Outras dicas

Considere usar o padrão da biblioteca padrão inspect Módulo-geralmente é a abordagem mais útil da introspecção, empacotando pedaços substanciais de funcionalidade (você pode implementá-lo do zero, mas reutilizar o código bem projetado é uma coisa boa). Ver http://docs.python.org/library/inspect.html para todos os detalhes, mas por exemplo inspect.getmembers(foo, inspect.ismethod) é uma excelente maneira de obter todos os métodos de foo (você receberá (name, value) pares classificados pelo nome).

que me diz rigorosamente falando que todos os métodos são atributos.mas eu não posso chamar um método sem a () assim, parece-me que o hasattr() é enganosa.

Por que é enganosa?Se obj.ban() é um método e, em seguida, obj.ban é o atributo correspondente.Você pode ter um código como este:

print obj.getValue()

ou

get = obj.getValue
print get()

Se você deseja obter uma lista de métodos em um objeto, você pode tentar esta função.Ele não é perfeito, pois também irá disparar para exigível atributos que não são métodos, mas para 99% dos casos, deve ser bom o suficiente:

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

este info O módulo inspirado do mergulho em python serve ao propósito.

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)

Há um método incorporado chamado chamável. Você pode aplicá -lo a qualquer objeto e ele retornará verdadeiro/falso, dependendo, se puder ser chamado. por exemplo

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

NOTA A chamada local () retornará um dicionário que contém tudo definido no seu escopo atual. Eu fiz isso porque os itens fora do dicionário são apenas strings e precisamos executar o chamável no objeto real.

Idealmente, quando um complicado biblioteca como BeautifulSoup, você deve consultar sua documentação para verificar quais são os métodos de cada classe oferece.No entanto, em raros casos em que você não possua fácil acesso a documentação, você pode verificar a presença de métodos usando o seguinte.

Todos os métodos, que são objetos, implementar o __call__ método e pode ser verificada usando o callable() método que retorna True, se o valor a ser verificada tem o __call__ o método.

O seguinte código deve funcionar.

x = Die()
x.roll()

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

O código acima deve retornar true para todos os métodos e false para não exigível atributos (tais como membros de dados como de proibição).No entanto, este método retorna True para qualquer capital exigível objetos (como classes internas).você também pode verificar se o tipo do atributo é instancemethod

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top