среда, 14 декабря 2011 г.

Технические задачки





1. Что будет выведено в результате исполнения программы? Почему?
class A:
     def __init__(self, name):
          self.name = name
     def __del__(self):
          print self.name,
 
aa = [A(str(i)) for i in range(3)]
for a in aa:
    del a

Вывод узнать легко в любой IDE. Это 2 1 0. Вопрос почему? Исходя из порядка(он если что, обратен созданию), можно догадаться, что тут задействован стек, т.е. работает правило LIFO.
При удалении списка - элементы удаляются в обратном порядке созданию.
Но важно понять, что удаление происходит в нашем случае, всего лишь когда скрипт отработал, а инструкция del тут ни при чём!
Вызов инструкции del рвёт связь имени переменной(в нашем случае a) и данных, находящихся в памяти, т.е. в цикле мы создаём ссылку на элемент списка, дём ей название->a, выводим name элемента и рвём связь. Чтобы отработал магический метод __del__ нужно вызывать del напрямую к элементу, т.е. через индекс, например del a[0]


2. Что будет выведено в результате исполнения программы? Почему?
class A:
    def __init__( self ):
        self.__value = 1
    def getvalue( self ):
        return self.__value
 
class B( A ):
    def __init__( self ):
        A.__init__( self )
        self.__value = 2
 
b = B()
print b.getvalue() == b.__value
Ответ: случится Exception, потому что невозможно получить доступ к __value извне класса. Однако самое интересное, здесь другое. В данном случае b.getvalue() возвращает 1, т.к. self.__value различно в каждом контексте. А именно b._A__value и b._B__value!



3. Есть 2 таблицы users и messages
users
UID Name
1 «Вася»
2  «Петя»


messages
UID msg
1 “A”
1 “B”
2 “C”

Напишите SQL-запрос, результатом которого будет таблица из двух полей: «Имя пользователя» и «Общее количество сообщений».
Здесь, могу посоветовать -  SELECT INTO
UPD добавил пример)
CREATE TABLE cvc.users(
 uid INT,
 name varchar(100)
);

CREATE TABLE cvc.messages(
 uid INT,
 msg varchar(100)
);

INSERT INTO cvc.users (uid, name) VALUES (1, 'Vasja'), (2, 'Petja');
INSERT INTO cvc.messages (uid, msg) VALUES (1, 'A'), (1, 'B'), (2, 'C');

select name, count(*) as cnt from cvc.users join cvc.messages on users.uid = messages.uid group by users.uid;
select name, count(*) as cnt from cvc.users, cvc.messages where users.uid = messages.uid group by users.uid;

DROP TABLE cvc.users;
DROP TABLE cvc.messages;

6 комментариев:

  1. Интересные примеры. А не подскажите может есть книжка которая раскрывает именно тонкости языка и работы интерпретатора?

    ОтветитьУдалить
  2. Рад, что заинтересовало вас. К сожалению, чего-то конкретного посоветовать не могу. Лучшая книга по Python для меня Лутца. А что касается интерпретатора, то в принципе их работа в языках обобщена и тут просто интересно почитать про их работу не привязываясь к языку. Интересная статья по Python здесь http://www.helloworld.ru/texts/comp/lang/python/python2/index.htm в сравнении с другими языками и затронуты более низкая реализация.

    ОтветитьУдалить
  3. Всё верно) Через SELECT INTO просто могли бы сразу в таблицу залить. Ну и тем, кто быть может только начинает, хочу добавить, что обычный select с выражением where - это и есть join. Т.е. можно написать и так просто
    select name, count(*) as cnt from users, messages where users.uid = messages.uid group by users.uid;

    ОтветитьУдалить
  4. И конечно же уже в ответе на первый вопрос — ошибка. Почитаете что такое del и как он работает: http://docs.python.org/reference/simple_stmts.html#the-del-statement а конкретно, третий абзац.

    ОтветитьУдалить
    Ответы
    1. Может я не прав, но мне кажется, что вы ошиблись ссылкой. Данная задачка описана тут http://docs.python.org/reference/datamodel.html#object.__del__
      а именно в блоке Note. del x doesn’t directly call x.__del__() — the former decrements the reference count for x by one, and the latter is only called when x‘s reference count reaches zero.
      Вроде всё верно.

      Удалить
    2. В данном примере вызов del вообще ничего не делает, ссылки на объекты все-равно сохранены в списке, удаление объектов происходит в порядке обратном созданию объектов, а не обратном вызову del X

      Удалить