crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Python, вопрос о переменных
Litkevich Yuriy
  опции профиля:
сообщение 12.11.2010, 15:21
Сообщение #1


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


чем отличаются две переменные, к которым присваивание осуществляется так:
myvar = ...
self.myvar = ...

может быть первая локальная, а вторая член класса?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Novak
  опции профиля:
сообщение 12.11.2010, 22:30
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 319
Регистрация: 15.3.2008
Из: Замкадыш
Пользователь №: 121

Спасибо сказали: 28 раз(а)




Репутация:   6  


Первое - это переменная, вторая - по сути поле, тоже переменная, у другого объекта. На самом деле происходит поиск атрибута "myvar" у объекта "self"
В питоне в фукнции у класса первым параметром передаётся переменная-объект, аналог this в плюсах
Принято, что первый параметр у такой функции называется self
Потому вторую запись чаще всего можно встретить в определении класса:
class MyClass:
    def print_message(self, message):
        print "Message: %s"%message


Сообщение отредактировал Novak - 12.11.2010, 22:43
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 12.11.2010, 22:41
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


я смотрел описание класса, там в одной функции использовались переменные и так и так.
но, те которые были без self, они как локальные в Си++ (например, создание компоновщиков, которые в других местах не нужны).
А те, что с self использовались и в других функциях класса.


Ещё вызывает запарку сама динамическая типизация.
Если мне нужна переменная-член класса, то нужно просто написать
self.var = ...

и всё? Т.е. self сделает своё дело, да?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Novak
  опции профиля:
сообщение 12.11.2010, 22:58
Сообщение #4


Активный участник
***

Группа: Участник
Сообщений: 319
Регистрация: 15.3.2008
Из: Замкадыш
Пользователь №: 121

Спасибо сказали: 28 раз(а)




Репутация:   6  


self - это просто переменная. в функциях класса она ссылается на объект, т.е. это не какое-то ключевое слово.
Другими словами, в функцию класса передаётся объект параметром, явно.
Через эту переменную можно получить доступ к полям объекта.
Область видимости этой переменной такая же, как и у всех, объявленных внутри текущей фукнции - это сама функция.
В рамках класса можно сделать вот так:
class A(object):
    def func1(self):
        var1 = 3 # здесь var1 и self - по сути, одинковые переменные. var1 ссылается на объект типа Int, self - на объект типа A
        self.val = var1 # тут мы полю val объекта типа A присваиваем значение переменной va1
    def func2(notself):
        print notself.val # тут у нас просто переменная, можно сказать, локальная, которая ссылается на объет типа A

object1 = A()
object1.func1() # вызываем сначала первую фукнцию, у объекта переменной object1 появляется поле val
object1.func2() # а тут выводится значение этого поля
# будем вызвать наоборот - получим ошибку, что у объекта нет атрибута val
object2 = A()
try:
    object2.func2() # у объекта пока нет поля val
except Exception as e:
    print e

Результаты:

3


Потому рекомендуется все используемые поля без крайней необходимости объявлять сразу явно, или в теле класса, или в конструкторе-функции __init__

Да, не забывай, что в питоне все переменные - ссылки на объекты. Потому и можно ими так легко играться.

Сообщение отредактировал Novak - 12.11.2010, 23:02
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 12.11.2010, 23:04
Сообщение #5


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


так-так, тогда получается, что я не правильно портирую:
    def mouseMoveEvent(event):
        if not self.m_embedded and (event.buttons() & Qt.LeftButton):
            move(pos() + event.globalPos() - self.m_dragPosition);
            self.m_dragPosition = event.globalPos();
            event.accept();
здесь я в функции писал только один входной аргумент (как и было в Си++), тогда получается self-а нет?

оригинальный код:
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    if (!m_embedded && (event->buttons() & Qt::LeftButton)) {
        move(pos() + event->globalPos() - m_dragPosition);
        m_dragPosition = event->globalPos();
        event->accept();
    }
}
здесь переменные m_* - члены класса
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Novak
  опции профиля:
сообщение 12.11.2010, 23:15
Сообщение #6


Активный участник
***

Группа: Участник
Сообщений: 319
Регистрация: 15.3.2008
Из: Замкадыш
Пользователь №: 121

Спасибо сказали: 28 раз(а)




Репутация:   6  


Если это просто функция класса, то без "селфа" никак. У тебя в любом случае первым параметром передаётся текущий объект.
иначе просто неоткуда такой переменной, как self взяться.
Т.е. тебе нужно добавить его в объявление
...
    def mouseMoveEvent(self, event):
...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 12.11.2010, 23:19
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Novak @ 13.11.2010, 3:15) *
Если это просто функция класса, то без "селфа" никак.
значит ли это, что в каждой функции класса обязан быть хотя бы один аргумент - self?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Novak
  опции профиля:
сообщение 12.11.2010, 23:26
Сообщение #8


Активный участник
***

Группа: Участник
Сообщений: 319
Регистрация: 15.3.2008
Из: Замкадыш
Пользователь №: 121

Спасибо сказали: 28 раз(а)




Репутация:   6  


Не обязательно с таким именем, но если ты попытаешься объявить вообще без параметров - вылетит исключение. Питон хочешь или не хочешь, объект передаёт, а там уже ты разбирайся :)
А исключение, что характерно, появится только при попытке использовать эту функцию
class A(object):
    def func():
        print "Oh, no"

object =A()
print 'I am alive'
object.func()

Результат:

I am alive
Traceback (most recent call last):
File "/Users/novak/git/py_koans/py_koans/python 2/koans/test.py", line 10, in <module>
object.func()
TypeError: func() takes no arguments (1 given)


При передаче лишнего параметра также вылезет исключение:
class A(object):
    def func(self):
        print "Oh, no"

object =A()
print 'I am alive'
object.func()
object.func(1)

Результат:

I am alive
Oh, no
Traceback (most recent call last):
File "/Users/novak/git/py_koans/py_koans/python 2/koans/test.py", line 11, in <module>
object.func(1)
TypeError: func() takes exactly 1 argument (2 given)

Сообщение отредактировал Novak - 12.11.2010, 23:24
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.6.2022, 10:04