访问类方法到实例方法的最佳方法

时间:2017-07-18 17:35:23

标签: python python-2.7 python-3.x class-method

--Pragmas are needed additionally for the project in which this snippet is included
{-# LANGUAGE TypeInType, DataKinds, PolyKinds, ScopedTypeVariables,
  FlexibleInstances, FlexibleContexts, GADTs, TypeFamilies,
  RankNTypes, LambdaCase, TypeOperators, TemplateHaskell,
  ConstraintKinds, PolyKinds, NoImplicitPrelude,
  UndecidableInstances, MultiParamTypeClasses, GADTSyntax,
  AllowAmbiguousTypes, InstanceSigs, DeriveFunctor,
  FunctionalDependencies #-}

-- Algebra.Graph is from the algebraic-graphs package
import qualified Algebra.Graph as AG
import Data.Singletons
import Data.Singletons.Prelude
import Data.Singletons.TypeLits
import Data.Kind


data T (ln::Nat) c = T c

class Edge operation n o 

instance 
  -- This would be something like: (LengthIsValidPrime x ~ True, y ~ DependentlyTypedCalculationForOpabc x) => 
  Edge (T l c) x y

data Flow :: * -> * where
        Empty :: Flow (a)
        Vertex :: (Edge a n o) => a -> Flow (a)
        Connect ::
            (Edge a x y, Edge a y z, Edge a x z) =>
            Flow (a) -> Flow (a) -> Flow (a)
        Overlay ::
            (Edge a x y, Edge a y z, Edge a x z) =>
            Flow (a) -> Flow (a) -> Flow (a)



type Test c = Connect (Vertex (T 24 c )) (Vertex (T 3 c))
--which fails with

--error:
--    • Illegal constraint in a type: Edge a0 x0 z0
--    • In the type ‘Connect (Vertex (T  24 c)) (Vertex (T 3 c))’
--      In the type declaration for ‘Test’

-- We want to be able to define a graph like so: 
type InputNode c = Vertex (T 100 c )
type ForkNode c = Vertex (T 10 c )
type NodeB c = Vertex (T 1  c )
type NodeC c = Vertex (T 1  c )
type PathA c = Connect (InputNode c) (ForkNode c)
type PathAB c = Connect (PathA c) (NodeB c)
type PathAC c = Connect (PathA c) (NodeC c)
type Output c = Vertex (T 2 c )
type Subgraph c = Overlay (Connect (PathAC c) (Output c)) (Connect (PathAB c) (Output c))

-- and eventually the trascription from the type-level graph to a value graph defined by Algebra.Graph
--foldFlow :: Flow a -> AG.Graph (Flow a)
--foldFlow Empty         = AG.empty
--foldFlow vt@(Vertex x) = AG.vertex vt
--foldFlow (Overlay x y) = AG.overlay  (foldFlow x) (foldFlow y)
--foldFlow (Connect x y) = AG.connect  (foldFlow x) (foldFlow y)
--runGraph :: Subgraph c
--runGraph = ...create a term-level Subgraph c so we can fold over it.

我有两种方法可以将类方法访问到实例方法中。

class Test(object):

    def __init__(self):
        pass

    def testmethod(self):
        # instance method
        self.task(10)      # type-1 access class method

        cls = self.__class__ 
        cls.task(20)        # type-2 access class method 

    @classmethod 
    def task(cls,val)
        print(val)

self.task(10)

我的问题是哪一个是最好的,为什么?

如果两种方式不相同,那么我在哪种情况下使用哪一种?

1 个答案:

答案 0 :(得分:4)

self.task(10)绝对是最好的。

首先,两者最终将以类实例的相同操作结束:

  

类实例
...
特殊属性:__ dict__是属性字典; __class__是实例的类

  • 使用类实例对象调用classmethod实际上将对象的类传递给方法(参考:参考手册的相同章节):
  

...通过从类或实例中检索类方法对象来创建实例方法对象时,其__self__属性就是类本身

但第一个更简单,不需要使用特殊属性。