Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 10, 2017 10:18:46

noob_saibot
Зарегистрирован: 2013-09-11
Сообщения: 495
Репутация: +  20  -
Профиль   Отправить e-mail  

ООП общение объектов

JOHN_16
noob_saibotпоясните, лучше с примером
 class Test:
    def blah(e):
        print(1)
Test.blah(None)
Python 3.*
 1
Python 2.*
 Traceback (most recent call last):
  File "C:/work/kgAll/temp.py", line 8, in <module>
    Test.blah(None)
TypeError: unbound method blah() must be called with Test instance as first argument (got NoneType instance instead)

Отредактировано noob_saibot (Фев. 10, 2017 10:20:33)

Офлайн

#2 Фев. 10, 2017 12:17:04

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

ООП общение объектов

noob_saibot
Думаю вы не правы. Рассмотри Ваш пример несколько иначе

 class Test:
    def blah(value):
        print(value * 10)
Test.blah(2)
Test().blah(2)
Вы же не зря в своем примере писали blah(e), не ясно толкьо осознанно или нет.
В примере выше согласно вашему высказыванию мы имеем статичный метод, однако это не так:
 ----> 6 Test().blah(2)
TypeError: blah() takes 1 positional argument but 2 were given
Дело в том что blah для класса Test это обычная функция, не прикрепленная к классу. Но когда речь идет о экземпляре класса, то это blah рассматривается не как обычная функция, а метод:
 In [15]: Test.blah
Out[15]: <function __main__.Test.blah>
In [16]: Test().blah
Out[16]: <bound method Test.blah of <__main__.Test object at 0x1027bf588>>
И вполне заслуженно ожидает что blah первым аргументом будет принимать ссылку на экземпляр класса

Теперь давайте рассмотрим настоящий статичный метод:
 class Test2:
    @staticmethod
    def blah(value):
        print(value * 100)
Test2.blah(2)
Test2().blah(2)
Он отработает без ошибок и выдаст ожидаемый результат. Потому что и в случае класса и в случае экземпляра - blah будет оставаться функцией:
 In [17]: Test2.blah
Out[17]: <function __main__.Test2.blah>
In [18]: Test2().blah
Out[18]: <function __main__.Test2.blah>



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#3 Фев. 10, 2017 14:11:08

noob_saibot
Зарегистрирован: 2013-09-11
Сообщения: 495
Репутация: +  20  -
Профиль   Отправить e-mail  

ООП общение объектов

JOHN_16
noob_saibotДумаю вы не правы. Рассмотри Ваш пример несколько иначе
Да, вас понял, был не прав, назвав visit статическим методом. Что же касается вызова ТС-ом - Konura.visit(dog), то работать будет в python3 как обычная функция, во 2.* будет unbound методом, что и вызовет ошибку.

Офлайн

#4 Фев. 10, 2017 16:39:14

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

ООП общение объектов

noob_saibot
то работать будет в python3 как обычная функция
Это скорее минус нововведений третьего питона, чем плюс.
Если не проверять тип аргумента, то можно получить абсурдное непредсказуемое поведение.



Офлайн

#5 Фев. 11, 2017 07:48:14

quix
Зарегистрирован: 2012-06-23
Сообщения: 105
Репутация: +  0  -
Профиль   Отправить e-mail  

ООП общение объектов

Про статические методы я понял (Большое спасибо - ценно)
Так всё же. Как реализовать отношения на уравне
экземпляров класса и МЕТОДОВ?

Офлайн

#6 Фев. 11, 2017 08:38:32

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

ООП общение объектов

quix

   
class DogHouse(object):
  
    def __init__(self, width, height):
        self.width = width
        self.height = height
  
    def try_dog(self, dog):
        return dog.width <= self.width and dog.height <= self.height
  
class Breed(object):
  
    def __init__(self, min_width,
                       min_height,
                       max_width,
                       max_height):
        self.min_width = min_width
        self.min_height = min_height
        self.max_width = max_width
        self.max_height = max_height
  
    def feed(self, w, h):
        return w + 1, h + 1
  
class Dog(object):
  
    def __init__(self, name, breed):
        self.name = name
        self.breed = breed
        self.width = breed.min_width
        self.height = breed.min_height
        self.house = None
  
    def settle(self, house):
        if not house.try_dog(self):
            raise ValueError("{} is too big".format(self.name))
        self.house = house
  
    def feed(self):
        new_width, new_height = self.breed.feed(self.width, self.height)
        if new_width <= self.breed.max_width and self.height <= self.breed.max_height:
            if self.house:
                if not self.house.try_dog(self):
                    raise ValueError("{} needs new house".format(self.name))
            self.width = new_width
            self.height = new_height
    def __repr__(self):
        return "Dog: {name}, {w}x{h}".format(name=self.name, w=self.width, h=self.height)
 
if __name__ == "__main__":
   
    class BigDog(Breed):
   
        def feed(self, w, h):
            return w + 3, h + 2
   
    poodle = Breed(1, 1, 20, 20)
    shepherd = BigDog(5, 5, 40, 60)
   
    kennel = [Dog("Tuzick", shepherd),
              Dog("Bobick", poodle),
              Dog("Anzor", shepherd),
              Dog("Fifa", poodle),
              Dog("Peppa", poodle),
              ]
   
    house1 = DogHouse(15, 15)
    house2 = DogHouse(30, 30)
    house3 = DogHouse(10, 10)
   
    kennel[0].settle(house1)
    kennel[2].settle(house2)
     
    for _ in range(100):
        for dog in kennel:
            try:
                dog.feed()
            except ValueError, e:
                print(e.message)
            print dog
    
    kennel[2].settle(house3)



Офлайн

#7 Фев. 11, 2017 18:31:18

quix
Зарегистрирован: 2012-06-23
Сообщения: 105
Репутация: +  0  -
Профиль   Отправить e-mail  

ООП общение объектов

FishHook
quix
 class DogHouse(object):
  
    def __init__(self, width, height):
        self.width = width
        self.height = height
  
    def try_dog(self, dog):
        return dog.width <= self.width and dog.height <= self.height
Разъясите что такое dog.width
чем занята точка в данном случае?
Спасибо.

Офлайн

#8 Фев. 12, 2017 01:17:34

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

ООП общение объектов

dog это некий объект передаваемый в качестве аргумента метода try_dog. Точка это обращение к атрибуту объекта.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version