Computer368106 views
中学英語811710 views
高校生物551766 views
りんご209490 views
高校日本史190571 views
MathPython497343 views
世界の国564520 views
いろは3010814 views
中学社会668760 views
LaTeX962153 views
Help
Tools
NewsSpreadsheetCalendarBookkeepingMarkdown TablesSlidesTier ListPen ToolIllustrationCrayonWatercolorPixel ArtASCII ArtPerspectiveEndless StairsGraphMind MapER DiagramFamily TreeMemeCurved TextImage EditorMosaicRetro FilterPencil SketchSwirl EffectLine ArtOCR/HighlighterMakeup EditorFaviconVideo TrimmerScrolling VideoVideo TitleColor PickerColor ExtractorBonfireFireworksWater RippleWater SplashBreaking GlassWood GrainMarble TextureCSS ButtonIcon MakerBar ChartGrouped Bar ChartStacked Bar ChartPie ChartLine ChartArea ChartStacked Area ChartScatter Plot3D Bar Chart3D Pie ChartBar Chart RaceBubble ChartPopulation PyramidPictogramEarningsCandlestick ChartInvestment RiskMortgage SimulatorCalculatorMatrix CalculatorFunction GraphPolynomial ExpansionVenn DiagramField VisualizerRubik's Cube Group TheoryTraveling SalesmanVoronoi and DelaunayFractalColumn ArithmeticDraw Math FiguresArithmetic AnimationArithmetic Word ProblemsCounting with Tree DiagramsCube NetsRolling DiceCross SectionsMotion PathMechanicsWavesElectromagnetic WavesCapacitorsLight and LensesThermodynamicsHow Semiconductors WorkMolecular StructuresAtomic OrbitalsElectrochemical CellsChemical EquilibriumCrystal LatticesBuffer pHOrganic Reaction MapPeriodic TableComplex IonsDNA Double HelixCell DivisionMembrane ChannelsNerve ImpulseMuscle ContractionHormones and HomeostasisRock ClassificationWeatherConstellationsSolar and Lunar Eclipses3D ModelingFloor PlanSeismic StructuresIntersection TurnMaglevCooking AnimationOrigamiLive Viewer CountGeoJSON MapRailway MapPopulation MapCrime MapLand Price MapSchool MapShrine and Castle MapHouse of Representatives MapWord MapSolitaireReversiHakoiri MusumeChessHamburgerRippleSlide Puzzle MakerNeon PinballNovel MakerJapanese Typing PracticePiano Score EditorMusic TheoryShogi StrategyPiano Rhythm Game

English

Python のクラスベースデコレータ

デコレータは関数だけでなく、クラスとしても実装できます。状態を保持したい場合や、複雑なロジックを整理したい場合に有効です。

基本構造

クラスベースのデコレータは __init__ で関数を受け取り、__call__ でラッパー処理を行います。

from functools import wraps

class CountCalls:
    def __init__(self, func):
        wraps(func)(self)
        self.func = func
        self.count = 0
    
    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"{self.func.__name__}{self.count} 回呼ばれました")
        return self.func(*args, **kwargs)

使い方は関数デコレータと同じです。

@CountCalls
def say_hello():
    print("Hello!")

say_hello()  # say_hello は 1 回呼ばれました / Hello!
say_hello()  # say_hello は 2 回呼ばれました / Hello!

クラスなので、self.count のように状態を自然に保持できます。

引数を取るクラスデコレータ

引数を取る場合は、__init__ で引数を受け取り、__call__ で関数を受け取ります。

class Repeat:
    def __init__(self, n):
        self.n = n
    
    def __call__(self, func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for _ in range(self.n):
                result = func(*args, **kwargs)
            return result
        return wrapper

@Repeat(3)
def greet():
    print("Hi!")

@Repeat(3) でインスタンスが生成され、その __call__ にデコレート対象の関数が渡されます。関数ベースの 3 層ネストよりも構造が明確になることがあります。