Yanıtlar:
Gerçekten iki farklı şeyi karıştırıyorsunuz.
Kullanım dir()
, vars()
ya inspect
(kullandığım modül ilgilenen ne almak için __builtins__
; bunun yerine herhangi bir nesne kullanabilirsiniz örnek olarak).
>>> l = dir(__builtins__)
>>> d = __builtins__.__dict__
Bu sözlüğü istediğiniz gibi yazdırın:
>>> print l
['ArithmeticError', 'AssertionError', 'AttributeError',...
veya
>>> 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',
...
Etkileşimli hata ayıklayıcıda bir komut olarak güzel baskı da mevcuttur:
(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
cevabınızda neden modül hakkında daha fazla konuşmuyorsunuz ? Ben print_r veya var_dump için en yakın şey olduğunu düşünüyorum.
dir()
Öyleyse, tarafından listelenen özelliklerin arkasındaki değerlere nasıl erişirsiniz ? dir()
yalnızca bir ad listesi döndürür ve bunların tümü öznitelikte vars()
veya __dict__
öznitelikte bulunmaz .
Şununla vars()
karıştırmak istiyorsunuz pprint()
:
from pprint import pprint
pprint(vars(your_object))
vars()
basitçe __dict__
argümanını döndürür ve bu da dir()
hiçbir __dir__
yöntem olmaması durumunda da bunun geri dönüşüdür . dir()
Dediğim gibi bu yüzden ilk etapta kullanın .
dir()
tüm yerleşik şeyleri sana verir __str__
ve __new__
. var()
yapmaz.
__dict__
öznitelikleri olmayan kümelerde ve diğer nesnelerde başarısız olur .
def dump(obj):
for attr in dir(obj):
print("obj.%s = %r" % (attr, getattr(obj, attr)))
Yazarların tercihlerine göre, istisna işleme, ulusal / özel karakter baskısı, iç içe geçmiş nesnelere özyineleme vb. Şeyler ekleyen birçok 3. taraf işlevi vardır. Ama hepsi temelde buna bağlı.
getmembers()
işlevi standart inspect
modülde kullanabilirsiniz, ancak bunun genel olarak içgözlemin nasıl yapılacağını göstermesi açısından daha yararlı olacağını düşündüm.
__dict__
( __doc__
ve gibi __module__
). Ayrıca, __dict__
beyan edilen nesneler için hiç çalışmaz __slots__
. Genel olarak, __dict__
sözlükte dahili olarak depolanan kullanıcı düzeyi özelliklerini gösterir. dir () daha fazlasını gösterir.
__dict__
nitelik / üye içermez . Çılgınca ama gerçek olduğunu biliyorum. Yerleşik benzeri int
ve / str
veya re.MatchObject
s yaygın örneklerdir. Deneyin 'hello'.__dict__
, sonra deneyindir('hello')
dir'den bahsedildi, ancak bu yalnızca özelliklerin adlarını verecektir. Onların değerlerini de isterseniz __dict__'yi deneyin.
class O:
def __init__ (self):
self.value = 3
o = O()
İşte çıktı:
>>> o.__dict__
{'value': 3}
set
yok __dict__
, bu yüzden onlar için başarısız olacakAttributeError: 'set' object has no attribute '__dict__'
Bunu yapmak için "dir ()" işlevini kullanabilirsiniz.
>>> 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']
>>>
Bir başka yararlı özellik de yardım.
>>> 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
Nesnenin geçerli durumunu yazdırmak için şunları yapabilirsiniz:
>>> obj # in an interpreter
veya
print repr(obj) # in a script
veya
print obj
Sınıflarınız için tanım __str__
veya __repr__
yöntemler. Gönderen Python belgelerinde :
__repr__(self)
repr()
Bir nesnenin "resmi" dize temsilini hesaplamak için yerleşik işlev ve dize dönüşümleri (ters tırnaklar) tarafından çağrılır . Mümkünse, bu, aynı değere sahip bir nesneyi yeniden oluşturmak için kullanılabilecek geçerli bir Python ifadesi gibi görünmelidir (uygun bir ortam verilir). Bu mümkün değilse, "<... bazı yararlı açıklamalar ...>" biçiminde bir dize döndürülmelidir. Dönüş değeri bir dize nesnesi olmalıdır. Bir sınıf repr () öğesini tanımlar ancak tanımlamazsa__str__()
,__repr__()
, o sınıfın örneklerinin "gayri resmi" bir dize temsili gerektiğinde de kullanılır. Bu genellikle hata ayıklama için kullanılır, bu nedenle sunumun bilgi açısından zengin ve açık olması önemlidir.
__str__(self)
str()
Bir nesnenin "gayri resmi" dize temsilini hesaplamak için yerleşik işlev ve print deyimi tarafından çağrılır . Bu__repr__()
, geçerli bir Python ifadesi olması gerekliliğinden farklıdır : bunun yerine daha uygun veya özlü bir temsil kullanılabilir. Dönüş değeri bir dize nesnesi olmalıdır.
print "DEBUG: object value: " + repr(obj)
Kontrol etmeye değer olabilir -
Perl'in Data :: Dumper'ına eşdeğer bir Python var mı?
Benim tavsiyem şudur -
https://gist.github.com/1071857
Perl, nesne verilerini tekrar perl kaynak koduna çeviren Data :: Dumper adlı bir modüle sahip olduğuna dikkat edin (NB: kodu kaynağa geri çevirmez ve neredeyse her zaman çıktıdaki nesne yöntemi işlevlerini istemezsiniz). Bu kalıcılık için kullanılabilir, ancak ortak amaç hata ayıklamaktır.
Standart python pprint'in elde edemediği birkaç şey vardır, özellikle bir nesnenin örneğini gördüğünde alçalmayı durdurur ve size nesnenin dahili onaltılık işaretçisini verir (errr, bu işaretçi tarafından çok fazla kullanılmaz yol). Özetle, python tamamen bu büyük nesne yönelimli paradigma ile ilgilidir, ancak kutudan aldığınız araçlar nesnelerden başka bir şeyle çalışmak için tasarlanmıştır.
Perl Data :: Dumper, ne kadar derine gitmek istediğinizi kontrol etmenizi sağlar ve ayrıca dairesel bağlantılı yapıları da algılar (bu gerçekten önemlidir). Bu sürecin perl'de elde edilmesi temelde daha kolaydır, çünkü nesnelerin kutsamalarının ötesinde belirli bir sihri yoktur (evrensel olarak iyi tanımlanmış bir süreç).
Kullanmanızı tavsiye ederim 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__.
Çoğu durumda, __dict__
veya dir()
tuşlarını kullanarak istediğiniz bilgiyi alabilirsiniz. Daha fazla ayrıntıya ihtiyaç duyarsanız, standart kütüphane, etkileyici miktarda ayrıntı elde etmenizi sağlayan inceleme modülünü içerir . Bilginin gerçek nuggestlerinden bazıları şunlardır:
Eğer sadece "nesnem hangi öznitelik değerlerine sahip?" Arıyorsanız, o zaman dir()
ve __dict__
muhtemelen yeterlidir. Gerçekten keyfi nesnelerin mevcut durumunu kazmak istiyorsanız (python'da neredeyse her şeyin bir nesne olduğunu unutmayın), o zaman inspect
dikkate değer.
Bir nesnenin tüm geçerli özelliklerini ve değerlerini yazdırmak için yerleşik bir işlev var mı?
Hayır. En çok oylanan cevap bazı nitelikleri içermez ve kabul edilen cevap, kamuya açık olmayan API'lerin yöntemleri ve bölümleri de dahil olmak üzere tüm niteliklerin nasıl alınacağını gösterir . Ancak bunun için iyi bir yerleşik yerleşik işlev yoktur .
Kısa bir sonuç, kendiniz yazabilmenizdir, ancak genel API'nin bir parçası olan özellikleri ve diğer hesaplanmış veri tanımlayıcılarını hesaplar ve bunu istemeyebilirsiniz:
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))
Çok sayıda veri üyesi bulunan bir sınıfa şu anda en çok oylanan cevabın uygulanmasını gözlemleyin:
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))
sadece yazdırır:
{'baz': 'baz'}
Çünkü vars
sadece döndüren __dict__
bir nesnenin, ve bunu vars tarafından döndürülen dicti değiştirmek eğer öyleyse, bir kopya değil, aynı zamanda modifiye ediyoruz __dict__
nesnenin kendisi.
vars(obj)['quux'] = 'WHAT?!'
vars(obj)
İadeler:
{'baz': 'baz', 'quux': 'WHAT?!'}
- bu kötü çünkü quux ayarlamamamız gereken ve isim alanında olmamamız gereken bir özellik ...
Şu anda kabul edilen cevapta (ve diğerlerinde) tavsiyeyi uygulamak çok daha iyi değildir:
>>> 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']
Gördüğümüz gibi, dir
sadece hepsini döndürüyor (aslında sadece çoğu) bir nesneyle ilişkili isimlerin.
inspect.getmembers
, yorumlarda bahsedilen, benzer şekilde kusurlu - tüm isimleri ve değerleri .
Öğretirken öğrencilerime bir nesnenin anlamsal olarak açık API'sını sağlayan bir işlev oluşturuyorum:
def api(obj):
return [name for name in dir(obj) if name[0] != '_']
Bir nesnenin anlamsal ad alanının bir kopyasını sağlamak için bunu genişletebiliriz , ancak __slots__
atanmamış olanı hariç tutmamız gerekir ve "geçerli özellikler" isteğini ciddiye alırsak, hesaplanan özellikleri hariç tutmamız gerekir ( pahalı olabilirler ve "şu anki" olarak yorumlanamazlar):
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)}
Ve şimdi özelliği hesaplamıyoruz veya göstermiyoruz, quux:
>>> attrs(obj)
{'bar': 0, 'baz': 'baz', 'foo': ''}
Ama belki de mallarımızın pahalı olmadığını biliyoruz. Bunları da içerecek şekilde mantığı değiştirmek isteyebiliriz. Belki de bunun yerine diğer özel veri tanımlayıcılarını hariç tutmak istiyoruz .
O zaman bu işlevi daha da özelleştirmemiz gerekiyor. Ve böylece tam olarak ne istediğimizi sihirli bir şekilde bilen ve ona sağlayan yerleşik bir fonksiyona sahip olamayacağımız mantıklı. Bu, kendimizi yaratmamız gereken işlevselliktir.
Bunu yapan yerleşik bir işlev yoktur ve durumunuz için en semantik olarak en uygun olanı yapmanız gerekir.
FunctionType
. Ama çok yararlı - teşekkürler!
Metaprogramlama örneği Magic ile nesne dökümü :
$ cat Instagram Hesabındaki Resim ve Videoları 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
Tartışma olmadan:
$ python dump.py
<__main__.Data instance at 0x00A052D8>
İle 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>
Biraz modası geçmiş ama hala çalışıyor.
Bunu hata ayıklama için kullanıyorsanız ve her şeyin yinelenen bir dökümü istiyorsanız, kabul edilen cevap tatmin edici değildir, çünkü sınıflarınızın __str__
zaten iyi uygulamalara sahip olmasını gerektirir . Durum böyle değilse, bu çok daha iyi çalışır:
import json
print(json.dumps(YOUR_OBJECT,
default=lambda obj: vars(obj),
indent=1))
TypeError: vars() argument must have __dict__ attribute
Ppretty'i deneyin
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)
Çıktı:
__main__.A(_p = 8, foo = [0, 1, ..., 8, 9], s = 5)
Bu, tüm nesne içeriğini yinelemeli olarak json veya yaml girintili biçimde yazdırır:
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)
Sadece pprint'ten bahseden cevabı iptal ettim. Açık olmak gerekirse, karmaşık bir veri yapısındaki tüm değerleri görmek istiyorsanız , şöyle bir şey yapın:
from pprint import pprint
pprint(my_var)
Burada my_var ilgi alanınızdır. Kullandığımda pprint(vars(my_var))
hiçbir şeyim yoktu ve buradaki diğer cevaplar yardımcı olmadı veya yöntem gereksiz yere uzun gözüktü. Bu arada, benim özel durumumda, denetlediğim kodun sözlükleri sözlüğü vardı.
Bazı özel sınıflarla, yararsız bir <someobject.ExampleClass object at 0x7f739267f400>
tür çıktıyla sonuçlanabileceğinizi belirtmek gerekir . Bu durumda, bir __str__
yöntem uygulamanız veya diğer çözümlerden bazılarını denemeniz gerekebilir . Hala üçüncü taraf kütüphaneler olmadan tüm senaryolarda çalışan basit bir şey bulmak istiyorum.
"MyObject" i dökmek için:
from bson import json_util
import json
print(json.dumps(myObject, default=json_util.default, sort_keys=True, indent=4, separators=(',', ': ')))
Vars () ve dir () denedim; her ikisi de aradığım şey için başarısız oldu. vars () işe yaramadı çünkü nesnede __dict__ (istisnalar.TypeError: vars () argümanı __dict__ özniteliğine sahip olmalıdır). dir () aradığım şey değildi: sadece alan adlarının bir listesi, değerleri veya nesne yapısını vermiyor.
Ben json.dumps () varsayılan = json_util.default olmadan çoğu nesne için çalışacağını düşünüyorum, ama standart json serileştirici başarısız böylece nesnede bir datetime alanı vardı. Bkz . Python "JSON serileştirilebilir değil datetime.datetime" üstesinden gelmek için?
Neden basit bir şey olmasın:
for key,value in obj.__dict__.iteritems():
print key,value
for key,value in obj.__dict__.iteritems(): print key,value
?
pprint , veri yapılarınızın estetik açıdan hoş temsillerini üretmek için bir “güzel yazıcı” içerir. Formatlayıcı, yorumlayıcı tarafından doğru şekilde ayrıştırılabilen ve aynı zamanda bir insanın okuması kolay olan veri yapılarının temsillerini üretir. Çıktı mümkünse tek bir satırda tutulur ve birden çok satıra ayrıldığında girintilenir.
Sadece sesli uyarıyı deneyin .
Sadece baskı nesnesi değişkenleri ile değil, aynı zamanda güzel çıktılar ile de size yardımcı olacaktır:
class(NormalClassNewStyle):
dicts: {
},
lists: [],
static_props: 1,
tupl: (1, 2)
Herkes için mücadele ediyor
vars()
tüm öznitelikleri döndürmüyor. dir()
özniteliklerin değerlerini döndürmüyor.Aşağıdaki kod , değerlerinin tüm niteliklerini yazdırır obj
:
for attr in dir(obj):
try:
print("obj.{} = {}".format(attr, getattr(obj, attr)))
except AttributeError:
print("obj.{} = ?".format(attr))
Flask Hata Ayıklama Araç Çubuğunu deneyebilirsiniz.
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)
Bu, değişkenlerinizin bir sınıf içinde, __init__ içinde veya dışında nasıl tanımlandığına bakılmaksızın çalışır.
your_obj = YourObj()
attrs_with_value = {attr: getattr(your_obj, attr) for attr in dir(your_obj)}
__dict__
üyesi (re.MatchObject
örneğin) yok gibi görünüyor , ancak yerleşikdir()
tüm nesneler için çalışıyor.