python - 有没有办法访问类中init方法中的函数?

时间:2011-11-05 15:51:31

标签: python

我有以下代码:

class random_walk:
    #ns: number of steps
    #np: number of particles
    #dimension : choose between 1D or 2D
    def __init__(self,ns,np,dimension=None):
        self.ns=ns
        self.np=np
        self.dimension=dimension

        if  self.dimension==2:
            #--- These represent the orientation of movement ------------
            step=random.choice([[0, 1], [1, 0], [0, -1], [-1, 0]])
            def step2d(self,ns):
                return [step for i in range(ns)]

    #steps=table with trajectories that constitute from m steps
    def steps(self,ns):    
        return 2*sc.random.random_integers(0,1,size=self.ns)-1

如果我rw=random_walk(ns,np)然后rw.steps(ns)它就可以了。

但是,如果我尝试rw=random_walk(ns,np,dimension)然后rw.step2d(ns)它会给我:random_walk instance has no attribute 'step2d'

据我了解,这是因为step2d函数在init方法中。有没有办法访问它?

谢谢!

3 个答案:

答案 0 :(得分:1)

你想做什么;根据传递给实例方法的参数更改类签名,并没有多大意义。

你应该做的是定义两个类:

class random_walk:
    #ns: number of steps
    #np: number of particles
    #dimension : choose between 1D or 2D
    def __init__(self,ns,np,dimension=None):
        self.ns=ns
        self.np=np
        self.dimension=dimension

    #steps=table with trajectories that constitute from m steps
    def steps(self,ns):    
        return 2*sc.random.random_integers(0,1,size=self.ns)-1

class random_walk_2d(random_walk):

    def step2d(self,ns):
        return [step for i in range(ns)]

然后定义一个返回正确类的工厂函数:

def make_random_walk(ns, np, dimensions=None):
    if dimensions ==  2:
        return random_walk_2d(ns, np, 2)
    else:
        return random_walk(ns, np, dimensions)

答案 1 :(得分:0)

不可以在__init__方法之外访问它。您在该方法的范围内声明它,因此它绑定到该范围。如果要在外部访问它,则必须在其他地方声明它,例如作为类的(私有)方法。

顺便说一下。你的随机游走将不会按你期望的方式工作。您正在执行random.choice一次,然后使用该单个计算值构建长度为ns的列表。因此,您最终将获得所有步骤的相同方向。您必须在循环内部移动choice调用,因此每个步骤都是随机的。你可以使用发电机然后顺便说一句:

def step2d ( self, ns ):
    for i in range( ns ):
        yield random.choice([[0, 1], [1, 0], [0, -1], [-1, 0]])

答案 2 :(得分:0)

是的,您需要将step2d()方法实际放在类上,而不是__init__()方法中。 Python 可以让你动态地为你的实例添加一个方法,所以你可以在__init__()中像你一样定义它,然后如果维度是2那么将它添加到实例中,但它是友好的因为你还需要为它创建一个绑定方法包装器,否则它将无法正常工作。这也是一个糟糕的设计,并且会让看到你的代码的其他程序员感到困惑。所以不要这样做。

相反,要么:

  1. 为具有step2d()方法的2D对象提供不同的子类。您可以拥有一个工厂函数,该函数根据维度返回正确类的实例(或将工厂实现为基类__new__()的一部分)。

  2. 只需将step2d()定义为另一种方法;如果维度不是2,请点击顶部的self.dimension并提升TypeError。如下所示:

    def step2d(self, ns):
        if self.dimension != 2:
            raise TypeError("dimension must be 2")
        # continue with what to do if the dimensionality is 2