LINUX.ORG.RU

Сгруппировать составляющие класса

 , ,


1

3

Решил тут для разминки мозгов немного поучить Python и вспомнить навыки ООП (чего не сделаешь, чтобы не заниматься делами, хе-хе). Допустим, я хочу описать некоего абстрактного человека с вот такими характеристиками (не код, просто схема):

Person
|-name = 'John'
|-age = 40
|-face
  |-shape = 'round'
  |-color = 'bronzed'
|-body
  |-height = 'short'
  |-build = 'sturdy'
#и так далее...
Так вот, как получить структуру вроде той, что на схеме, чтобы потом писать, например, Person.face.shape? Нужно ли делать face и body классами внутри класса Person?

Нужно ли делать face и body классами внутри класса Person?

Да, но, если очень не хочется, можно взять что-нибудь вроде addict.

grazor ★★
()
Ответ на: комментарий от grazor

Спасибо за совет.

но, если очень не хочется

Да не то чтобы мне эта идея была глубоко противна :) Просто как-то странно кажется выносить в класс то, что больше похоже на сишную struct.

al_exquemelin ★★★
() автор топика
Ответ на: комментарий от al_exquemelin

Здесь есть несколько примеров как сделать attribute dictionary на коленке, заодно и про недостатки почитать можно.

Worron ★★★
()
Ответ на: комментарий от al_exquemelin

на сишную struct

На то Си и не ООП

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

Dred ★★★★★
()
Ответ на: комментарий от Dred

На то Си и не ООП

А чего не ООП-то? Нет, понятно, наследования и методов, привязанных к типу объектов, там нет. Но описать объект через typedef никто же не запрещает.

Проще тогда уж словари использовать

А как? Мне вот, наоборот, приходит в голову объединить при необходимости несколько Person в словарь: {'Mary': Person, 'John': Person, 'Bill': Person}.

al_exquemelin ★★★
() автор топика

Нужно ли делать face и body классами внутри класса Person

Нет, не нужно, если объекты face и body тебе где-то в другом месте не требуются. Можешь назвать faceShape и faceColor, ну ты понял в общем. А вот shape и color в нормальном ЯП я бы сделал enum-ом, в свежем питоне по идее должен быть тоже, но я толком питон не знаю.

peregrine ★★★★★
()
Ответ на: комментарий от al_exquemelin

Просто как-то странно кажется выносить в класс то, что больше похоже на сишную struct

Вам надо было на плюсах покодить, там суть struct и class одно и то же (что и правильно на самом деле, ИМХО), только по умолчанию в struct члены public, а в class private.

peregrine ★★★★★
()
Ответ на: комментарий от peregrine

Можешь назвать faceShape и faceColor

Да, я тоже подумал про одинаковые начала названий переменных, но это какое-то слабое подобие.

shape и color в нормальном ЯП я бы сделал enum-ом

А это зачем?

Вам надо было на плюсах покодить

Не, не хочу плюсы, хочу питон :)

al_exquemelin ★★★
() автор топика
Последнее исправление: al_exquemelin (всего исправлений: 1)
Ответ на: комментарий от al_exquemelin

А чего не ООП-то?

ООП это про инкапсуляцию, наследование и полиморфизм. Где это в C нормально есть? Конечно можно извратиться и написать Glib, но C это не ООП.

peregrine ★★★★★
()
Ответ на: комментарий от al_exquemelin

А это зачем?

Если там не рандом, вводимый пользователем или кем-то ещё, а ограниченный список вариантов, то лучше всего enum, чтобы не ошибиться случайно и не сделать лицо rond, вместо round, которое потом неправильно обрабатываться будет.

peregrine ★★★★★
()
Ответ на: комментарий от al_exquemelin

Ну может быть, я в питоне не очень силен, скорее очень слаб. Реально больше пары скриптов при помощи гугла мне на нем не приходилось делать.

peregrine ★★★★★
()
class Face:
    def __init__(self, shape, color):
        self.shape = shape
        self.color = color

class Person:
    def __init__(self, name, age, face):
        self.name = name
        self.age = age
        self.face =face

    def __repr__(self):
        return 'This is ' + self.name + ' with ' + self.face.color + ' face'

Vasya = Person('Vasya', 40, Face('round','bronzed'))
print(Vasya)

не благодари :)

Sahas ★★★★☆
()
Ответ на: комментарий от ei-grad

Collections? Спасибо, посмотрю.

Кстати, а чем вообще полезны кортежи, если в двух словах? Полистал мануал, но что-то дзен не сошёл на меня.

Sahas

не благодари :)

Так это же почти то, о чём я писал в начале темы, не? Учитывая, что Face будет только у Person, наверное, нет большой разницы, объявлять одно внутри другого или за пределами.

al_exquemelin ★★★
() автор топика
class Person:
    class Abstract:
        pass
    
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
        Person.Abstract.__getattr__ = Person.__getattr__
    
    def __getattr__(self, name):
        a = Person.Abstract()
        self.__dict__[name] = a
        return a
    
    def __str__(self):
        def format(d, ind='    '):
            r = ''
            for k,v in d.items():
                if type(v) is Person.Abstract:
                    r += f'{ind}{k.capitalize()}:\n' + format(v.__dict__, ind+'    ')
                else:
                    r += f'{ind}{k.capitalize()}:\t{v}\n'
            return r
        return 'Person:\n' + format(self.__dict__)


p = Person(name='Vasiliy Petrovich')
p.age = 22
p.face.shape = 'square'
p.body.height = 'tall'
p.what.e.v.e.r = ':)'

print(p)
anonymous
()

Нужно ли делать face и body классами внутри класса Person?

Можно, но не нужно.

no-such-file ★★★★★
()
Ответ на: комментарий от anonymous

уверен, что в модуле для yaml её нет?

Я уверен, что её не нужно писать самому.

no-such-file ★★★★★
()
Ответ на: комментарий от al_exquemelin

Учитывая, что Face будет только у Person, наверное, нет большой разницы, объявлять одно внутри другого или за пределами.

В данном случае это скорее вопрос вкуса. Но для моего примера строка

Vasya = Person('Vasya', 40, Face('round','bronzed'))
не будет работать, если Face внутри Person, надо будет, видимо, использовать что-то вроде Person.Face(...)

Sahas ★★★★☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.