Вопрос стиля Python: Поддержка класса как внутреннего класса? - PullRequest
3 голосов
/ 19 января 2011

Мне нравится использовать структуры, встроенные в язык, для организации моего кода.Но есть одна ситуация, когда я не могу оставаться последовательным просто потому, что не вижу определенного лучшего способа сделать это.Это касается вспомогательных классов, то есть классов, которые исключительно используются внутри другого класса: я делаю их внутренними классами или отдельными классами.

Внутренние классы:

class Complicated:
    class Utility1:
        pass
    class Utility2:
        pass
    pass

Отдельные классы:

class Complicated:
    pass

class Utility1:
    pass

class Utility2:
    pass

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

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

Мой вопрос состоит в том, может ли кто-либо с существенным опытом работы с питоном на спине посоветовать, есть ли лучшая практикав соответствии с этим?Даже если ответ таков, что «это зависит», будет полезно, если он придет с кем-то более опытным, чем я.

Ответы [ 4 ]

6 голосов
/ 19 января 2011

Я бы предложил

class Complicated:
    pass

class _Utility1:
    pass

class _Utility2:
    pass

и поместите все это в отдельный модуль. Ведущий _ указывает, что служебные классы предназначены только для внутреннего использования (и при этом они не будут импортированы from module import *; но мне это все равно не нравится).

Редактировать: Цитировать с PEP 8 :

Классы для внутреннего использования дополнительно имеют ведущее подчеркивание.

1 голос
/ 19 января 2011

Я использую одно подчеркивание в качестве префикса к классам, которые являются внутренними для пакетов python. Я думаю, что это общий шаблон Python:

class Complicated:
    pass

class _Utility1:
    pass

class _Utility2:
    pass
0 голосов
/ 28 мая 2016

Внутренние классы Python

Возможно создание и использование внутренних классов Python.В отличие от других языков, таких как Java, внутренние классы Python не предоставляют автоматически доступ к атрибутам и методам внешнего класса.

Обход этой проблемы: определите все внутренние классы с помощью родительского параметра.Этот параметр можно использовать для доступа к атрибутам и методам внешнего класса.

Пример класса Python с внутренним классом

class Outer:
    def __init__(self):
        self.myVar = 100
        self.inner = self.Inner(self)

    def getDoubleVar(self):
        return(self.myVar * 2)

    #Define inner class
    class Inner:
        def __init__(self, parent):
            self.parent = parent

        #Use the parent variable to access parent class attributes/methods
        def printOuterVar(self):
            print(self.parent.myVar)

        def callOuterMethod(self):
            return(self.parent.getDoubleVar())




#Create Instance of Outer Class
outer = Outer()

#Display myVar
print("Display myVar")
print(outer.myVar)


#Execute Outer Method
print("\nExecute Outer Method")
print("val = outer.getDoubleVar()")
val = outer.getDoubleVar()
print("val: {0}".format(val))

#Execute Inner Method
print("\nExecute Inner Method")
print("outer.inner.printOuterVar()")
outer.inner.printOuterVar()

#Execute Inner Method That Calls Outer Method
print("\nExecute Inner Method That Calls Outer Method")
val = outer.inner.callOuterMethod()
print("val = outer.inner.callOuterMethod()")
print("val: {0}".format(val))

#Create Instance of Inner Class Separately
print("\nInstantiate Inner Class Separately")
#Note that you provide the current outer instance as the parent parameter
print("Note that you provide the current outer instance as the parent parameter")
print("myInner = outer.Inner(outer)")
myInner = outer.Inner(outer)

#Call Inner Method
print("\nCall Inner Method")
print("myInner.printOuterVar()")
myInner.printOuterVar()
print("finished")
0 голосов
/ 19 января 2011

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

class Foo(object):
    normalize = str

    def process(self, input):
        # Do some stuff in here...
        return self.normalize(output)

class UniFoo(Foo):
    normalize = unicode

class TotallyMungedFoo(Foo):
    class normalize(object): ...

Если я не ожидаючтобы нуждаться (или явно не хотеть) в таком поведении, я использую классы в том же модуле, но включаю только «важный» в мое объявление __all__.

...