Respostas:
Você está realmente misturando duas coisas diferentes.
Use dir()
, vars()
ou o inspect
módulo para conseguir o que você está interessado em (eu uso __builtins__
como um exemplo, você pode usar qualquer objeto em seu lugar).
>>> l = dir(__builtins__)
>>> d = __builtins__.__dict__
Imprima esse dicionário da maneira que desejar:
>>> print l
['ArithmeticError', 'AssertionError', 'AttributeError',...
ou
>>> from pprint import pprint
>>> pprint(l)
['ArithmeticError',
'AssertionError',
'AttributeError',
'BaseException',
'DeprecationWarning',
...
>>> pprint(d, indent=2)
{ 'ArithmeticError': <type 'exceptions.ArithmeticError'>,
'AssertionError': <type 'exceptions.AssertionError'>,
'AttributeError': <type 'exceptions.AttributeError'>,
...
'_': [ 'ArithmeticError',
'AssertionError',
'AttributeError',
'BaseException',
'DeprecationWarning',
...
A impressão bonita também está disponível no depurador interativo como um comando:
(Pdb) pp vars()
{'__builtins__': {'ArithmeticError': <type 'exceptions.ArithmeticError'>,
'AssertionError': <type 'exceptions.AssertionError'>,
'AttributeError': <type 'exceptions.AttributeError'>,
'BaseException': <type 'exceptions.BaseException'>,
'BufferError': <type 'exceptions.BufferError'>,
...
'zip': <built-in function zip>},
'__file__': 'pass.py',
'__name__': '__main__'}
print re.compile(r'slots').search('No slots here either.').__slots__
inspect
módulo em sua resposta? Eu acho que é a coisa mais próxima de print_r ou var_dump.
dir()
, então? dir()
retorna apenas uma lista de nomes e nem todos existem no vars()
ou no __dict__
atributo
Você quer vars()
misturado com pprint()
:
from pprint import pprint
pprint(vars(your_object))
vars()
simplesmente retorna o __dict__
argumento e esse também é o substituto dir()
no caso de não haver __dir__
método. então use dir()
em primeiro lugar, como eu disse.
dir()
fornece todas as coisas incorporadas que você provavelmente não gosta __str__
e gosta __new__
. var()
não.
__dict__
atributo.
def dump(obj):
for attr in dir(obj):
print("obj.%s = %r" % (attr, getattr(obj, attr)))
Existem muitas funções de terceiros por aí que adicionam itens como tratamento de exceções, impressão de caracteres nacionais / especiais, recorrência em objetos aninhados etc. de acordo com as preferências de seus autores. Mas todos eles basicamente se resumem a isso.
getmembers()
função no inspect
módulo padrão , mas achei que isso seria mais útil, pois ilustra como fazer a introspecção em geral.
__dict__
(como __doc__
e __module__
). Além disso, __dict__
não funciona para objetos declarados com __slots__
. Em geral, __dict__
mostra propriedades no nível do usuário que são realmente armazenadas internamente em um dicionário. dir () mostra mais.
__dict__
atributo / membro. Eu sei que é loucura, mas é verdade. Built-ins como int
e str
ou re.MatchObject
s são exemplos comuns. Tente 'hello'.__dict__
, então tentedir('hello')
dir foi mencionado, mas isso fornecerá apenas os nomes dos atributos. Se você quiser os valores deles, tente __dict__.
class O:
def __init__ (self):
self.value = 3
o = O()
Aqui está a saída:
>>> o.__dict__
{'value': 3}
set
não tem __dict__
, por isso, para eles ele falhará comAttributeError: 'set' object has no attribute '__dict__'
Você pode usar a função "dir ()" para fazer isso.
>>> import sys
>>> dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__', '__stdin__', '__stdo
t__', '_current_frames', '_getframe', 'api_version', 'argv', 'builtin_module_names', 'byteorder
, 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dllhandle', 'exc_clear', 'exc_info'
'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval', 'getdefault
ncoding', 'getfilesystemencoding', 'getrecursionlimit', 'getrefcount', 'getwindowsversion', 'he
version', 'maxint', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_
ache', 'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setprofile', 'setrecursionlimit
, 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoption
', 'winver']
>>>
Outro recurso útil é a ajuda.
>>> help(sys)
Help on built-in module sys:
NAME
sys
FILE
(built-in)
MODULE DOCS
http://www.python.org/doc/current/lib/module-sys.html
DESCRIPTION
This module provides access to some objects used or maintained by the
interpreter and to functions that interact strongly with the interpreter.
Dynamic objects:
argv -- command line arguments; argv[0] is the script pathname if known
Para imprimir o estado atual do objeto, você pode:
>>> obj # in an interpreter
ou
print repr(obj) # in a script
ou
print obj
Para suas classes, defina __str__
ou __repr__
métodos. Na documentação do Python :
__repr__(self)
Chamado pelarepr()
função interna e por conversões de string (aspas reversas) para calcular a representação de string "oficial" de um objeto. Se possível, deve parecer uma expressão Python válida que possa ser usada para recriar um objeto com o mesmo valor (considerando um ambiente apropriado). Se isso não for possível, uma sequência no formato "<... alguma descrição útil ...>" deve ser retornada. O valor de retorno deve ser um objeto de sequência. Se uma classe define repr () mas não__str__()
, então__repr__()
também é usado quando uma representação de cadeia "informal" de instâncias dessa classe é necessária. Isso geralmente é usado para depuração, por isso é importante que a representação seja rica em informações e inequívoca.
__str__(self)
Chamado pelastr()
função interna e pela instrução print para calcular a representação de cadeia "informal" de um objeto. Isso difere do__repr__()
fato de não precisar ser uma expressão válida do Python: uma representação mais conveniente ou concisa pode ser usada. O valor de retorno deve ser um objeto de sequência.
print "DEBUG: object value: " + repr(obj)
Pode valer a pena conferir --
Existe um Python equivalente ao Data :: Dumper do Perl?
Minha recomendação é esta -
https://gist.github.com/1071857
Observe que o perl possui um módulo chamado Data :: Dumper, que converte os dados do objeto de volta ao código-fonte perl (NB: NÃO converte o código de volta ao código-fonte, e quase sempre você não deseja que o método de objeto funcione na saída). Isso pode ser usado para persistência, mas o objetivo comum é a depuração.
Há várias coisas que o python pprint padrão não consegue, em particular, ele apenas para de descer quando vê uma instância de um objeto e fornece o ponteiro hexadecimal interno do objeto (errr, esse ponteiro não é muito usado por o caminho). Então, em poucas palavras, python é tudo sobre esse ótimo paradigma orientado a objetos, mas as ferramentas que você obtém da caixa são projetadas para trabalhar com algo diferente de objetos.
O perl Data :: Dumper permite controlar a profundidade que você deseja ir e também detecta estruturas circulares vinculadas (isso é realmente importante). Esse processo é fundamentalmente mais fácil de ser realizado em perl, porque os objetos não têm mágica em particular além de suas bênçãos (um processo universalmente bem definido).
Eu recomendo usar help(your_object)
.
help(dir)
If called without an argument, return the names in the current scope. Else, return an alphabetized list of names comprising (some of) the attributes of the given object, and of attributes reachable from it. If the object supplies a method named __dir__, it will be used; otherwise the default dir() logic is used and returns: for a module object: the module's attributes. for a class object: its attributes, and recursively the attributes of its bases. for any other object: its attributes, its class's attributes, and recursively the attributes of its class's base classes.
help(vars)
Without arguments, equivalent to locals(). With an argument, equivalent to object.__dict__.
Na maioria dos casos, usar __dict__
ou dir()
obterá as informações desejadas. Se precisar de mais detalhes, a biblioteca padrão inclui o módulo de inspeção , que permite obter uma quantidade impressionante de detalhes. Alguns dos verdadeiros nuggests de informações incluem:
Se você está apenas procurando "quais valores de atributo meu objeto possui?", Então dir()
e __dict__
provavelmente são suficientes. Se você está realmente procurando cavar o estado atual de objetos arbitrários (tendo em mente que em python quase tudo é um objeto), então inspect
é digno de consideração.
Existe uma função interna para imprimir todas as propriedades e valores atuais de um objeto?
Não. A resposta mais votada exclui alguns tipos de atributos e a resposta aceita mostra como obter todos os atributos, incluindo métodos e partes da API não pública. Mas não há nenhuma boa completo builtin função para isso.
Portanto, o corolário curto é que você pode escrever seu próprio, mas ele calculará propriedades e outros descritores de dados calculados que fazem parte da API pública, e talvez você não queira isso:
from pprint import pprint
from inspect import getmembers
from types import FunctionType
def attributes(obj):
disallowed_names = {
name for name, value in getmembers(type(obj))
if isinstance(value, FunctionType)}
return {
name: getattr(obj, name) for name in dir(obj)
if name[0] != '_' and name not in disallowed_names and hasattr(obj, name)}
def print_attributes(obj):
pprint(attributes(obj))
Observe a aplicação da resposta atualmente mais votada em uma classe com muitos tipos diferentes de membros de dados:
from pprint import pprint
class Obj:
__slots__ = 'foo', 'bar', '__dict__'
def __init__(self, baz):
self.foo = ''
self.bar = 0
self.baz = baz
@property
def quux(self):
return self.foo * self.bar
obj = Obj('baz')
pprint(vars(obj))
apenas imprime:
{'baz': 'baz'}
Como retorna vars
apenas o __dict__
de um objeto e não é uma cópia, por isso, se você modificar o ditado retornado por vars, também estará modificando o __dict__
próprio objeto.
vars(obj)['quux'] = 'WHAT?!'
vars(obj)
retorna:
{'baz': 'baz', 'quux': 'WHAT?!'}
- o que é ruim porque o quux é uma propriedade que não devemos definir e não deve estar no espaço para nome ...
A aplicação do conselho na resposta atualmente aceita (e outras) não é muito melhor:
>>> dir(obj)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'bar', 'baz', 'foo', 'quux']
Como podemos ver, dir
apenas retorna todos (na verdade, apenas a maioria) dos nomes associados a um objeto.
inspect.getmembers
, mencionado nos comentários, é igualmente falho - retorna todos os nomes e valores.
Ao ensinar, meus alunos criam uma função que fornece a API semanticamente pública de um objeto:
def api(obj):
return [name for name in dir(obj) if name[0] != '_']
Podemos estender isso para fornecer uma cópia do espaço de nomes semântico de um objeto, mas precisamos excluir os __slots__
que não foram atribuídos e, se levarmos a sério o pedido de "propriedades atuais", precisamos excluir as propriedades calculadas (como eles podem se tornar caros e podem ser interpretados como não "atuais"):
from types import FunctionType
from inspect import getmembers
def attrs(obj):
disallowed_properties = {
name for name, value in getmembers(type(obj))
if isinstance(value, (property, FunctionType))}
return {
name: getattr(obj, name) for name in api(obj)
if name not in disallowed_properties and hasattr(obj, name)}
E agora não calculamos ou mostramos a propriedade, quux:
>>> attrs(obj)
{'bar': 0, 'baz': 'baz', 'foo': ''}
Mas talvez saibamos que nossas propriedades não são caras. Podemos querer alterar a lógica para incluí-los também. E talvez desejemos excluir outro costume descritores de dados .
Então, precisamos personalizar ainda mais essa função. E, portanto, faz sentido que não possamos ter uma função interna que saiba magicamente exatamente o que queremos e a forneça. Essa é a funcionalidade que precisamos criar para nós mesmos.
Não existe uma função interna que faça isso, e você deve fazer o que é semanticamente mais apropriado para sua situação.
FunctionType
. Mas muito útil - obrigado!
Um exemplo de metaprogramação Despejar objeto com magia :
$ cat dump.py
#!/usr/bin/python
import sys
if len(sys.argv) > 2:
module, metaklass = sys.argv[1:3]
m = __import__(module, globals(), locals(), [metaklass])
__metaclass__ = getattr(m, metaklass)
class Data:
def __init__(self):
self.num = 38
self.lst = ['a','b','c']
self.str = 'spam'
dumps = lambda self: repr(self)
__str__ = lambda self: self.dumps()
data = Data()
print data
Sem argumentos:
$ python dump.py
<__main__.Data instance at 0x00A052D8>
Com o Gnosis Utils :
$ python dump.py gnosis.magic MetaXMLPickler
<?xml version="1.0"?>
<!DOCTYPE PyObject SYSTEM "PyObjects.dtd">
<PyObject module="__main__" class="Data" id="11038416">
<attr name="lst" type="list" id="11196136" >
<item type="string" value="a" />
<item type="string" value="b" />
<item type="string" value="c" />
</attr>
<attr name="num" type="numeric" value="38" />
<attr name="str" type="string" value="spam" />
</PyObject>
Está um pouco desatualizado, mas ainda está funcionando.
Se você está usando isso para depuração e deseja apenas um despejo recursivo de tudo, a resposta aceita é insatisfatória porque exige que suas classes já tenham boas __str__
implementações. Se não for esse o caso, isso funciona muito melhor:
import json
print(json.dumps(YOUR_OBJECT,
default=lambda obj: vars(obj),
indent=1))
TypeError: vars() argument must have __dict__ attribute
Tente ppretty
from ppretty import ppretty
class A(object):
s = 5
def __init__(self):
self._p = 8
@property
def foo(self):
return range(10)
print ppretty(A(), show_protected=True, show_static=True, show_properties=True)
Resultado:
__main__.A(_p = 8, foo = [0, 1, ..., 8, 9], s = 5)
Isso imprime todo o conteúdo do objeto recursivamente no formato indentado json ou yaml:
import jsonpickle # pip install jsonpickle
import json
import yaml # pip install pyyaml
serialized = jsonpickle.encode(obj, max_depth=2) # max_depth is optional
print json.dumps(json.loads(serialized), indent=4)
print yaml.dump(yaml.load(serialized), indent=4)
Votou a resposta que menciona apenas pprint. Para ser claro, se você deseja ver todos os valores em uma estrutura de dados complexa, faça algo como:
from pprint import pprint
pprint(my_var)
Onde my_var é sua variável de interesse. Quando usei, pprint(vars(my_var))
não obtive nada e as outras respostas aqui não ajudaram ou o método pareceu desnecessariamente longo. A propósito, no meu caso particular, o código que eu estava inspecionando tinha um dicionário de dicionários.
Vale ressaltar que, com algumas classes personalizadas, você pode acabar tendo um <someobject.ExampleClass object at 0x7f739267f400>
tipo de saída inútil . Nesse caso, talvez você precise implementar um __str__
método ou tentar algumas das outras soluções. Ainda gostaria de encontrar algo simples que funcione em todos os cenários, sem bibliotecas de terceiros.
Eu estava precisando imprimir as informações de DEBUG em alguns logs e não consegui usar o pprint, pois isso iria quebrá-lo. Em vez disso, fiz isso e consegui praticamente a mesma coisa.
DO = DemoObject()
itemDir = DO.__dict__
for i in itemDir:
print '{0} : {1}'.format(i, itemDir[i])
Para despejar "myObject":
from bson import json_util
import json
print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=(',', ': ')))
Eu tentei vars () e dir (); ambos falharam pelo que eu estava procurando. vars () não funcionou porque o objeto não tinha __dict__ (exceptions.TypeError: o argumento vars () deve ter o atributo __dict__). dir () não era o que eu estava procurando: é apenas uma lista de nomes de campos, não fornece os valores ou a estrutura do objeto.
Eu acho que json.dumps () funcionaria para a maioria dos objetos sem o padrão = json_util.default, mas eu tinha um campo datetime no objeto para que o serializador json padrão falhasse. Consulte Como superar "datetime.datetime não JSON serializable" em python?
Por que não algo simples:
for key,value in obj.__dict__.iteritems():
print key,value
for key,value in obj.__dict__.iteritems(): print key,value
?
O pprint contém uma "impressora bonita" para produzir representações esteticamente agradáveis de suas estruturas de dados. O formatador produz representações de estruturas de dados que podem ser analisadas corretamente pelo intérprete e também são fáceis para o ser humano ler. A saída é mantida em uma única linha, se possível, e recuada quando dividida em várias linhas.
Apenas tente impressão .
Isso o ajudará não apenas com a impressão de variáveis de objetos, mas também com uma saída bonita, como esta:
class(NormalClassNewStyle):
dicts: {
},
lists: [],
static_props: 1,
tupl: (1, 2)
Para todo mundo lutando com
vars()
não retornando todos os atributos. dir()
não retornando os valores dos atributos.O código a seguir imprime todos os atributos de obj
com seus valores:
for attr in dir(obj):
try:
print("obj.{} = {}".format(attr, getattr(obj, attr)))
except AttributeError:
print("obj.{} = ?".format(attr))
Você pode tentar a barra de ferramentas Flask Debug.
https://pypi.python.org/pypi/Flask-DebugToolbar
from flask import Flask
from flask_debugtoolbar import DebugToolbarExtension
app = Flask(__name__)
# the toolbar is only enabled in debug mode:
app.debug = True
# set a 'SECRET_KEY' to enable the Flask session cookies
app.config['SECRET_KEY'] = '<replace with a secret key>'
toolbar = DebugToolbarExtension(app)
Eu gosto de trabalhar com chaves ou valores internos de tipos de objetos python .
Para atributos, independentemente de serem métodos ou variáveis:
o.keys()
Para valores desses atributos:
o.values()
Isso funciona, independentemente de como suas variáveis sejam definidas dentro de uma classe, dentro de __init__ ou fora.
your_obj = YourObj()
attrs_with_value = {attr: getattr(your_obj, attr) for attr in dir(your_obj)}
__dict__
membro (re.MatchObject
por exemplo), mas o builtindir()
funciona para todos os objetos.