[Tutor] questions when define a class

Peter Otten __peter__ at web.de
Tue Apr 15 15:46:39 CEST 2014


Qianyun Guo wrote:

> Hi all, I am trying to get a suffix tree from a string. I use three
> classes, Node, Edge, SuffixTree. I have two questions when implementing:
> 
> 【1】
> 
>>>> a = Edge(1,2,3,4)
> 
>>>> a.length
> 
> 1
> if I remove  '@property' in my code, it returns as below:
> 
>>>> a = Edge(1,2,3,4)
> 
>>>> a.length
> 
> <bound method Edge.length>
> 
>>>> a.length()
> 
> 1
> 
> 
> 
> I don't really understand the differences w/ @property, and the
> differences of a.length and a.length(), could you explain?

Properties are a way to calculate attributes:

>     @property
>     def length(self):
>         return self.last_char_index - self.first_char_index

In client code

obj.length

looks like an attribute, but does a calculation under the hood. This is 
particularly useful to keep a changing interface compatible to prior 
versions:

version 1, everybody uses cartesian coordinates:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

version 2, polar coordinates are so much better ;)

class Point:
    def __init__(self, r, phi):
        self.r = r
        self.phi = phi
    @property
    def x(self):
        return self.r * math.cos(self.phi)
    @property
    def y(self):
        return self.r * math.sin(self.phi)
 
Thanks to properties our new point can be passed to functions that expect 
cartesian coords. Without properties we'd either end up writing a trivial 
wrapper

def get_x(self):
   return self.x

for every attribute (the Java way) and never use attributes directly or we'd 
have to change all occurences of point.x to point.x().

> 【2】
> 
> In SuffixTree, I define two functions, _get_str_from_edge,
> _get_str_from_node, the latter depend on the first one (please see my
> code).  Then I have this problem:
> 
>>>> a = SuffixTree('abcd')
> 
>>>> a._get_str_from_edge(a.edges[(0,1)])
> 
> 'abcd$'
> 
>>>> a._get_str_from_node(0,1)
> 
> TypeError: _get_str_from_edge() takes exactly 2 arguments (3 given)
> 
> Could you tell me what's wrong here?

>     def _get_str_from_node(self, source_node_index, dest_node_index):
>         return self._get_str_from_edge(self,
>         self.edges[(source_node_index,
> \
>                 dest_node_index)])

self._get_str_from_edge

gives you a "bound method", i. e. one that already knows about self. Invoke 
it as

     return self._get_str_from_edge(
          self.edges[(source_node_index,
                      dest_node_index)])

By the way, the backslash is not necessesary as long as there are open 
parens. Preferred:

(1 + # no backslash
2)

Obsolete alternative:
1 + \
2





More information about the Tutor mailing list