2014-02-14 2 views
0

Python style вопрос.Переменная, содержащая classobj - хороший стиль?

Иногда я задаю классы переменных, так что я могу создать экземпляр их в другом месте, например:

class GuitarItem(): 
    pass 

class SuperClass(): 
    def get_instance(self): 
     return self.Item() 

class SubClass(SuperClass): 
    Item = GuitarItem 

class SubClass2(SuperClass): 
    Item = PianoItem 

Это хороший стиль? Я пропустил более идиоматический способ сделать это? Меня это беспокоит, потому что item не заглавный (как переменная), поэтому он «выглядит» как вызов метода.

ОБНОВЛЕНИЕ: В соответствии с комментариями от Hyperboreus я капитализирую Item, который выглядит более разумным для меня. В противном случае это кажется абсолютно прекрасным.

+0

Каждый класс уже имеет имя (тот, с которым был объявлен, и который был передан 'type()'). Поэтому нет ничего плохого в том, чтобы давать им больше имен по мере необходимости. – Hyperboreus

+0

@Hyperboreus, так что вышесказанное не выглядит странным для вас .. вы напишете его так же? – HorseloverFat

+0

Я бы воспользовался переменной. Что-то вроде 'Thing = LinuxThing if os == 'linux' else NoLinuxThing', являясь классами' LinuxThing' и 'NoLinuxThing'. Но не спрашивайте меня о стиле. Я часто нахожусь здесь на SO, потому что я не придерживаюсь PEP-8. – Hyperboreus

ответ

1

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

#! /usr/bin/python3 

class GuitarItem: pass 

class PianoItem: pass 

class SuperClass: 
    def makeItem (self): #or whatever you want to do with the Item class 
     return type (self).Item() 

class SubClass (SuperClass): Item = GuitarItem 

class SubClass2 (SuperClass): Item = PianoItem 

print (SubClass().makeItem()) 
print (SubClass2().makeItem()) 

Это сначала создаст гитару, а затем и фортепиано.

0

Я бы предложил использовать шаблон фабричного метода, потому что он очень похож на то, что вы сделали, и промышленность знает этот шаблон. http://en.wikipedia.org/wiki/Factory_method_pattern

class GuitarItem(): pass 
class PianoItem(): pass 

class SuperClass(): 

    def __init__(self) 
     self.item_instance = self.new_item() 

    def new_item(self): 
     """Explain why it should provide item.""" 
     raise NotImplementedError("Subclass of SuperClass must provide new_item method") 


class SubClass(SuperClass): 
    def new_item(self): 
     return GuitarItem() 

class SubClass2(SuperClass): 
    def new_item(self): 
     return PianoItem() 
+0

OK, что означает перевод «Factory pattern» вышеприведенного кода? Я действительно не «понимаю», что многие шаблоны проектирования ООП выглядят как на Python, так что это мне очень поможет. – HorseloverFat

+3

Тот факт, что классы и функции являются гражданами первого класса на питоне, устраняет необходимость таких мерзостей, как фабричные шаблоны. Я думаю, что это в основном болезнь Java. – Hyperboreus

+0

ОК, возможно, это мне тогда не поможет ;-) – HorseloverFat

2

Чтобы решить ваш главный вопрос:

Иногда я задаю классы переменных, так что я могу создать экземпляр их в другом месте (...) Это хороший стиль? Я пропустил более идиоматический способ для этого?

классы языка Python (а также функции, методы, модули и т.д.) являются простым объектом, так же как и все остальное, так что да, это «хороший стиль» и нет, нет «более идиоматических путь».

Это беспокоит меня, потому что элемент не капитализирован (как переменная), так что это выглядит как вызов метода.

Это фактически заканчивает тем, что вызов метода (это вызов __call__ метод метакласса, который, в свою очередь, называет __new__ метод класса). Кроме того, FWIW вам все равно, действительно ли item является классом, любое возвращаемое возвращаемым ожидаемым объектом будет (и будет) работать, так что это не имеет никакого отношения к CamelCasing.

+1

+1. И ваш последний абзац интересен. Предположим, что у меня есть 'class Item: pass' и где-то еще' ThisSpecialItemClass = Item' или 'this_special_item_class = Item' с наружным верхом на камне, как вы предлагаете. В чем разница между именем 'Item' и' this_special_item_class'? Разве они не оба названия для класса и должны быть записаны в одном корпусе? – Hyperboreus

+0

@Hyperboreus кажется логичным использовать переменную, поскольку они оба являются именами для классов, но хотелось бы видеть руководство по этому вопросу, если оно существует. PEP8, похоже, не разъясняет это (если я не пропущу что-то). – HorseloverFat

+0

@Hyperboreus: разница в том, что 'Item' является каноническим именем класса - тем, которое вы увидите, если вы напечатаете Item. FWIW, соглашение для 'classmethods' и большинство функций/методов, которые ожидают, что класс как аргумент, должен называть аргумент' cls' (строчный). –

Смежные вопросы