Как получить более подробную информацию об объекте (список полей и методов), используя pdb Python? - PullRequest
2 голосов
/ 02 апреля 2012

Я использую pdb (на самом деле ipdb) для отладки моего Django models.py.В частности, я пытаюсь отладить эти строки кода:

def add_can_view( sender, **kwargs ) :
    #import ipdb; ipdb.set_trace()
    for content_type in ContentType.objects.all():
        Permission.objects.create(
            content_type = content_type,
            codename     = 'view_{}'.format( content_type.model ),
            name         = 'Can view {}'.format( content_type.name )
        )

post_syncdb.connect( add_can_view )

Приведенный выше код, который был предоставлен в этом вопросе , имеет ошибку IntegrityError при запуске python manage.py syncdb:

ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (11, 0))
---------------------------------------------------------------------------
IntegrityError                            Traceback (most recent call last)
/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/IPython/utils/py3compat.pyc in execfile(fname, *where)
    173             else:
    174                 filename = fname
--> 175             __builtin__.execfile(filename, *where)

/Users/hobbes3/Sites/mysite/manage.py in <module>()
      8     from django.core.management import execute_from_command_line
      9 
---> 10     execute_from_command_line(sys.argv)

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/core/management/__init__.pyc in execute_from_command_line(argv)
    441     """
    442     utility = ManagementUtility(argv)
--> 443     utility.execute()
    444 
    445 def execute_manager(settings_mod, argv=None):

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/core/management/__init__.pyc in execute(self)
    380             sys.stdout.write(self.main_help_text() + '\n')
    381         else:
--> 382             self.fetch_command(subcommand).run_from_argv(self.argv)
    383 
    384 def setup_environ(settings_mod, original_settings_path=None):

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/core/management/base.pyc in run_from_argv(self, argv)
    194         options, args = parser.parse_args(argv[2:])
    195         handle_default_options(options)
--> 196         self.execute(*args, **options.__dict__)
    197 
    198     def execute(self, *args, **options):

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/core/management/base.pyc in execute(self, *args, **options)
    230             if self.requires_model_validation:
    231                 self.validate()
--> 232             output = self.handle(*args, **options)
    233             if output:
    234                 if self.output_transaction:

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/core/management/base.pyc in handle(self, *args, **options)
    369         if args:
    370             raise CommandError("Command doesn't accept any arguments")
--> 371         return self.handle_noargs(**options)
    372 
    373     def handle_noargs(self, **options):

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/South-0.7.4-py2.7.egg/south/management/commands/syncdb.pyc in handle_noargs(self, migrate_all, **options)
     88 
     89         # OK, run the actual syncdb

---> 90         syncdb.Command().execute(**options)
     91 
     92         settings.INSTALLED_APPS = old_installed

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/core/management/base.pyc in execute(self, *args, **options)
    230             if self.requires_model_validation:
    231                 self.validate()
--> 232             output = self.handle(*args, **options)
    233             if output:
    234                 if self.output_transaction:

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/core/management/base.pyc in handle(self, *args, **options)
    369         if args:
    370             raise CommandError("Command doesn't accept any arguments")
--> 371         return self.handle_noargs(**options)
    372 
    373     def handle_noargs(self, **options):

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/core/management/commands/syncdb.pyc in handle_noargs(self, **options)
    108         # Send the post_syncdb signal, so individual apps can do whatever they need

    109         # to do at this point.

--> 110         emit_post_sync_signal(created_models, verbosity, interactive, db)
    111 
    112         # The connection may have been closed by a syncdb handler.


/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/core/management/sql.pyc in emit_post_sync_signal(created_models, verbosity, interactive, db)
    187         models.signals.post_syncdb.send(sender=app, app=app,
    188             created_models=created_models, verbosity=verbosity,
--> 189             interactive=interactive, db=db)

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/dispatch/dispatcher.pyc in send(self, sender, **named)
    170 
    171         for receiver in self._live_receivers(_make_id(sender)):
--> 172             response = receiver(signal=self, sender=sender, **named)
    173             responses.append((receiver, response))
    174         return responses

/Users/hobbes3/Sites/mysite/doors/signals.py in add_can_view(sender, **kwargs)
      8             content_type = content_type,
      9             codename     = 'view_{}'.format( content_type.model ),
---> 10             name         = 'Can view {}'.format( content_type.name )
     11         )
     12 

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/db/models/manager.pyc in create(self, **kwargs)
    135 
    136     def create(self, **kwargs):
--> 137         return self.get_query_set().create(**kwargs)
    138 
    139     def bulk_create(self, *args, **kwargs):

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/db/models/query.pyc in create(self, **kwargs)
    375         obj = self.model(**kwargs)
    376         self._for_write = True
--> 377         obj.save(force_insert=True, using=self.db)
    378         return obj
    379 

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/db/models/base.pyc in save(self, force_insert, force_update, using)
    461         if force_insert and force_update:
    462             raise ValueError("Cannot force both insert and updating in model saving.")
--> 463         self.save_base(using=using, force_insert=force_insert, force_update=force_update)
    464 
    465     save.alters_data = True

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/db/models/base.pyc in save_base(self, raw, cls, origin, force_insert, force_update, using)
    549 
    550                 update_pk = bool(meta.has_auto_field and not pk_set)
--> 551                 result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
    552 
    553                 if update_pk:

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/db/models/manager.pyc in _insert(self, objs, fields, **kwargs)
    201 
    202     def _insert(self, objs, fields, **kwargs):
--> 203         return insert_query(self.model, objs, fields, **kwargs)
    204 
    205     def _update(self, values, **kwargs):

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/db/models/query.pyc in insert_query(model, objs, fields, return_id, raw, using)
   1574     query = sql.InsertQuery(model)
   1575     query.insert_values(fields, objs, raw=raw)
-> 1576     return query.get_compiler(using=using).execute_sql(return_id)
   1577 
   1578 

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/db/models/sql/compiler.pyc in execute_sql(self, return_id)
    908         cursor = self.connection.cursor()
    909         for sql, params in self.as_sql():
--> 910             cursor.execute(sql, params)
    911         if not (return_id and cursor):
    912             return

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/db/backends/util.pyc in execute(self, sql, params)
     38         start = time()
     39         try:
---> 40             return self.cursor.execute(sql, params)
     41         finally:
     42             stop = time()

/Users/hobbes3/.virtualenvs/doors/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.pyc in execute(self, query, args)
     50     def execute(self, query, args=None):
     51         try:
---> 52             return self.cursor.execute(query, args)
     53         except Database.IntegrityError, e:
     54             raise utils.IntegrityError, utils.IntegrityError(*tuple(e)), sys.exc_info()[2]

IntegrityError: duplicate key value violates unique constraint "auth_permission_content_type_id_codename_key"
DETAIL:  Key (content_type_id, codename)=(2, view_group) already exists.

У меня такое ощущение, что почему-то есть дубликат content_type, и возникает ошибка, когда я дважды пытаюсь применить разрешение к content_type_id 2, то есть auth.group.Поэтому, когда я раскомментирую строку import ipdb, я хочу проверить некоторые объекты, такие как content_type, но если я наберу это, то получу только <ContentType: content type>.

Я знаю, что могу простопосмотрите на документацию , чтобы увидеть модель, но как вы получите список полей и методов, не зная, что это за класс?

Также бонусные баллы за решение этой ошибки lol.

Ответы [ 3 ]

3 голосов
/ 02 апреля 2012

Используйте dir (например, dir(content_type)), чтобы получить список атрибутов (включая методы).

Что касается моделей django, то в свойстве _meta также содержится много информации. Исследуйте это с dir(my_model_object._meta).

2 голосов
/ 02 апреля 2012

Ваш выбор:

  1. dir , чтобы получить список атрибутов и методов объекта

  2. content_type.__class__ для изучения класса объекта

  3. поможет показать документацию в консоли, чтобы вам не пришлось ее искать

1 голос
/ 30 марта 2015

Поскольку вы используете ipdb (а не pdb), более быстрая альтернатива dir использует встроенное завершение табуляции:

ipdb> foo=""
ipdb> foo.           #press tab after writing the dot
foo.capitalize  foo.islower     foo.rpartition
foo.center      foo.isspace     foo.rsplit
foo.count       foo.istitle     foo.rstrip
foo.decode      foo.isupper     foo.split
foo.encode      foo.join        foo.splitlines
foo.endswith    foo.ljust       foo.startswith
foo.expandtabs  foo.lower       foo.strip
foo.find        foo.lstrip      foo.swapcase
foo.format      foo.partition   foo.title
foo.index       foo.replace     foo.translate
foo.isalnum     foo.rfind       foo.upper
foo.isalpha     foo.rindex      foo.zfill
foo.isdigit     foo.rjusthere

В случае, если вы этого не сделаетезнать об этом, вы также можете использовать табуляцию для завершения имен переменных

...