Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #75251 > unrolled thread

Return class.

Started bySatish ML <satishmlwizpro@gmail.com>
First post2014-07-26 11:29 -0700
Last post2014-07-26 12:15 -0700
Articles 8 — 2 participants

Back to article view | Back to comp.lang.python


Contents

  Return class. Satish ML <satishmlwizpro@gmail.com> - 2014-07-26 11:29 -0700
    Re: Return class. Chris Angelico <rosuav@gmail.com> - 2014-07-27 04:40 +1000
      Re: Return class. Satish ML <satishmlwizpro@gmail.com> - 2014-07-26 12:02 -0700
      Re: Return class. Satish ML <satishmlwizpro@gmail.com> - 2014-07-26 12:03 -0700
      Re: Return class. Satish ML <satishmlwizpro@gmail.com> - 2014-07-26 12:04 -0700
        Re: Return class. Chris Angelico <rosuav@gmail.com> - 2014-07-27 05:16 +1000
      Re: Return class. Satish ML <satishmlwizpro@gmail.com> - 2014-07-26 12:21 -0700
    Re: Return class. Satish ML <satishmlwizpro@gmail.com> - 2014-07-26 12:15 -0700

#75251 — Return class.

FromSatish ML <satishmlwizpro@gmail.com>
Date2014-07-26 11:29 -0700
SubjectReturn class.
Message-ID<23517efd-6d71-4182-9f18-7aaae3b95afb@googlegroups.com>
Hi,

What does "return Wrapper" do in the following piece of code? Which method does it invoke?
I mean "return Wrapper" invokes __init__ method?

def Tracer(aClass):
    class Wrapper:
        def __init__(self, *args, **kargs):
            self.fetches = 0
            self.wrapped = aClass(*args, **kargs)
        def __getattr__(self, attrname):
            print('Trace: ' + attrname)
            self.fetches += 1
            print(self.fetches)
            return getattr(self.wrapped, attrname)
    return Wrapper


Actual program:

def Tracer(aClass):
    class Wrapper:
        def __init__(self, *args, **kargs):
            self.fetches = 0
            self.wrapped = aClass(*args, **kargs)
        def __getattr__(self, attrname):
            print('Trace: ' + attrname)
            self.fetches += 1
            print(self.fetches)
            return getattr(self.wrapped, attrname)
    return Wrapper
@Tracer
class Spam:
    def __init__(self, *args):
        print(*args)
    def display(self):
        print('Spam!' * 8)

@Tracer
class Person:
    def __init__(self, name, hours, rate):
        self.name = name
        self.hours = hours
        self.rate = rate
    def pay(self):
        return self.hours * self.rate

food = Spam("CARST")
food.display()
print([food.fetches])

bob = Person('Bob', 40, 50)
print(bob.name)
print(bob.pay())

print('')
sue = Person('Sue', rate=100, hours=60)
print(sue.name)
print(sue.pay())

print(bob.name)
print(bob.pay())
print([bob.fetches, sue.fetches])

[toc] | [next] | [standalone]


#75253

FromChris Angelico <rosuav@gmail.com>
Date2014-07-27 04:40 +1000
Message-ID<mailman.12353.1406400496.18130.python-list@python.org>
In reply to#75251
On Sun, Jul 27, 2014 at 4:29 AM, Satish ML <satishmlwizpro@gmail.com> wrote:
> What does "return Wrapper" do in the following piece of code? Which method does it invoke?
> I mean "return Wrapper" invokes __init__ method?
>
> def Tracer(aClass):
>     class Wrapper:
>         def __init__(self, *args, **kargs):
>             self.fetches = 0
>             self.wrapped = aClass(*args, **kargs)
>         def __getattr__(self, attrname):
>             print('Trace: ' + attrname)
>             self.fetches += 1
>             print(self.fetches)
>             return getattr(self.wrapped, attrname)
>     return Wrapper
>

It doesn't invoke anything. It returns the class itself - a callable,
subclassable thing, which wraps the passed-in class. When it's used as
a decorator, what happens is that first the basic class gets
constructed, then it gets passed to this function, and whatever this
function returns becomes the resulting class. So, taking the simplest
example:

@Tracer
class Spam:
    def __init__(self, *args):
        print(*args)
    def display(self):
        print('Spam!' * 8)

This is like doing this:

class Spam:
    def __init__(self, *args):
        print(*args)
    def display(self):
        print('Spam!' * 8)
Spam = Tracer(Spam)

And then Tracer begins executing, with the Spam class as "aClass". It
constructs a new class with two methods: an __init__ which passes
everything through to the wrapped class and retains the resulting
object, and a __getattr__ which proxies through to the original with
tracing facilities.

But all it does is construct and return that class. It doesn't call
anything, yet. Calling the class (instantiating an object of it)
happens when the Spam("CARST") call happens; instead of calling the
original Spam class, it calls the special wrapper, which then calls on
the original.

You can look up class decorators in the Python docs; they're not
something you'll use often (and they're something you'll write even
less often), but they can give you a lot of flexibility.

ChrisA

[toc] | [prev] | [next] | [standalone]


#75254

FromSatish ML <satishmlwizpro@gmail.com>
Date2014-07-26 12:02 -0700
Message-ID<2f69e9c6-6d81-4fc4-bb39-889846842f75@googlegroups.com>
In reply to#75253
Which line of code is printing [4] and [4, 5, 6, 7] in the output?

from tracer import Tracer
@Tracer
class MyList(list):
    def __init__(self, *args):
        print("INSIDE MyList")
        print(*args)
        x = MyList([1, 2, 3])
x.append(4)
print(x.wrapped)
WrapList = Tracer(list)
x = WrapList([4, 5, 6])
x.append(7)
print(x.wrapped)

OUTPUT:

CARST
Trace: display
1
Spam!Spam!Spam!Spam!Spam!Spam!Spam!Spam!
[1]
Trace: name
1
Bob
Trace: pay
2
2000

Trace: name
1
Sue
Trace: pay
2
6000
Trace: name
3
Bob
Trace: pay
4
2000
[4, 2]
INSIDE MyList
[1, 2, 3]
Trace: append
1
[4]
Trace: append
1
[4, 5, 6, 7]

[toc] | [prev] | [next] | [standalone]


#75255

FromSatish ML <satishmlwizpro@gmail.com>
Date2014-07-26 12:03 -0700
Message-ID<8026d86c-d963-41a1-bc90-9663a5462858@googlegroups.com>
In reply to#75253
Which line of code is printing [4] and [4, 5, 6, 7] in the output?

from tracer import Tracer
@Tracer
class MyList(list):
    def __init__(self, *args):
        print("INSIDE MyList")
        print(*args)
        x = MyList([1, 2, 3])
x.append(4)
print(x.wrapped)
WrapList = Tracer(list)
x = WrapList([4, 5, 6])
x.append(7)
print(x.wrapped)

OUTPUT:

CARST
Trace: display
1
Spam!Spam!Spam!Spam!Spam!Spam!Spam!Spam!
[1]
Trace: name
1
Bob
Trace: pay
2
2000

Trace: name
1
Sue
Trace: pay
2
6000
Trace: name
3
Bob
Trace: pay
4
2000
[4, 2]
INSIDE MyList
[1, 2, 3]
Trace: append
1
[4]
Trace: append
1
[4, 5, 6, 7]

[toc] | [prev] | [next] | [standalone]


#75256

FromSatish ML <satishmlwizpro@gmail.com>
Date2014-07-26 12:04 -0700
Message-ID<d2cf78fd-cc30-47ca-b6a4-4117bc843cf0@googlegroups.com>
In reply to#75253
Which line of code is printing [4] and [4, 5, 6, 7] in the output?

from tracer import Tracer
@Tracer
class MyList(list):
    def __init__(self, *args):
        print("INSIDE MyList")
        print(*args)
x = MyList([1, 2, 3])
x.append(4)
print(x.wrapped)
WrapList = Tracer(list)
x = WrapList([4, 5, 6])
x.append(7)
print(x.wrapped)

OUTPUT:

CARST
Trace: display
1
Spam!Spam!Spam!Spam!Spam!Spam!Spam!Spam!
[1]
Trace: name
1
Bob
Trace: pay
2
2000

Trace: name
1
Sue
Trace: pay
2
6000
Trace: name
3
Bob
Trace: pay
4
2000
[4, 2]
INSIDE MyList
[1, 2, 3]
Trace: append
1
[4]
Trace: append
1
[4, 5, 6, 7]

[toc] | [prev] | [next] | [standalone]


#75258

FromChris Angelico <rosuav@gmail.com>
Date2014-07-27 05:16 +1000
Message-ID<mailman.12354.1406402170.18130.python-list@python.org>
In reply to#75256
On Sun, Jul 27, 2014 at 5:04 AM, Satish ML <satishmlwizpro@gmail.com> wrote:
> Which line of code is printing [4] and [4, 5, 6, 7] in the output?

These lines:

> print(x.wrapped)

The .wrapped attribute has the wrapped object, so you're printing out
the thing that would be in x if you weren't using the decorator. Since
that's a subclass of list and doesn't change __str__ or __repr__, it
prints out like a list.

Tip: If you're not sure what line produces what output, tag them all.
Instead of print(x.wrapped), put print(1,x.wrapped), and have a
different number on every line of output. Then you'll easily see which
is which.

ChrisA

[toc] | [prev] | [next] | [standalone]


#75259

FromSatish ML <satishmlwizpro@gmail.com>
Date2014-07-26 12:21 -0700
Message-ID<4379f9cb-00d5-4809-ae02-d57085fdbe6f@googlegroups.com>
In reply to#75253
Hi,

Which lines of code prints [4] and [4, 5, 6, 7] in the output?


Output:

CARST
Trace: display
1
Spam!Spam!Spam!Spam!Spam!Spam!Spam!Spam!
[1]
Trace: name
1
Bob
Trace: pay
2
2000

Trace: name
1
Sue
Trace: pay
2
6000
Trace: name
3
Bob
Trace: pay
4
2000
[4, 2]
INSIDE MyList
[1, 2, 3]
Trace: append
1
[4]
Trace: append
1
[4, 5, 6, 7]

Actual Code:
def Tracer(aClass):
    class Wrapper:
        def __init__(self, *args, **kargs):
            self.fetches = 0
            self.wrapped = aClass(*args, **kargs)
        def __getattr__(self, attrname):
            print('Trace: ' + attrname)
            self.fetches += 1
            print(self.fetches)
            return getattr(self.wrapped, attrname)
    return Wrapper
@Tracer
class Spam:
    def __init__(self, *args):
        print(*args)
    def display(self):
        print('Spam!' * 8)

@Tracer
class Person:
    def __init__(self, name, hours, rate):
        self.name = name
        self.hours = hours
        self.rate = rate
    def pay(self):
        return self.hours * self.rate

food = Spam("CARST")
food.display()
print([food.fetches])

bob = Person('Bob', 40, 50)
print(bob.name)
print(bob.pay())

print('')
sue = Person('Sue', rate=100, hours=60)
print(sue.name)
print(sue.pay())


Another module that is producing output:

from tracer import Tracer
@Tracer
class MyList(list):
    def __init__(self, *args):
        print("INSIDE MyList")
        print(*args)
      
x = MyList([1, 2, 3])
x.append(4)
print(x.wrapped)
WrapList = Tracer(list)
x = WrapList([4, 5, 6])
x.append(7)
print(x.wrapped)

[toc] | [prev] | [next] | [standalone]


#75257

FromSatish ML <satishmlwizpro@gmail.com>
Date2014-07-26 12:15 -0700
Message-ID<5543493c-f927-4490-ba8d-06bdb7f255d3@googlegroups.com>
In reply to#75251
Actual program: 

def Tracer(aClass): 
    class Wrapper: 
        def __init__(self, *args, **kargs): 
            self.fetches = 0 
            self.wrapped = aClass(*args, **kargs) 
        def __getattr__(self, attrname): 
            print('Trace: ' + attrname) 
            self.fetches += 1 
            print(self.fetches) 
            return getattr(self.wrapped, attrname) 
    return Wrapper 
@Tracer 
class Spam: 
    def __init__(self, *args): 
        print(*args) 
    def display(self): 
        print('Spam!' * 8) 

@Tracer 
class Person: 
    def __init__(self, name, hours, rate): 
        self.name = name 
        self.hours = hours 
        self.rate = rate 
    def pay(self): 
        return self.hours * self.rate 

food = Spam("CARST") 
food.display() 
print([food.fetches]) 

bob = Person('Bob', 40, 50) 
print(bob.name) 
print(bob.pay()) 

print('') 
sue = Person('Sue', rate=100, hours=60) 
print(sue.name) 
print(sue.pay()) 

print(bob.name) 
print(bob.pay()) 
print([bob.fetches, sue.fetches]) 


Which line of code is printing [4] and [4, 5, 6, 7] in the output? 
Another module.
from tracer import Tracer 
@Tracer 
class MyList(list): 
    def __init__(self, *args): 
        print("INSIDE MyList") 
        print(*args) 
        x = MyList([1, 2, 3]) 
x.append(4) 
print(x.wrapped) 
WrapList = Tracer(list) 
x = WrapList([4, 5, 6]) 
x.append(7) 
print(x.wrapped) 

OUTPUT: 

CARST 
Trace: display 
1 
Spam!Spam!Spam!Spam!Spam!Spam!Spam!Spam! 
[1] 
Trace: name 
1 
Bob 
Trace: pay 
2 
2000 

Trace: name 
1 
Sue 
Trace: pay 
2 
6000 
Trace: name 
3 
Bob 
Trace: pay 
4 
2000 
[4, 2] 
INSIDE MyList 
[1, 2, 3] 
Trace: append 
1 
[4] 
Trace: append 
1 
[4, 5, 6, 7] 

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web