CONSTRUCT - Adding Functionality to the Overall System

S

Steve Holden

Ilias said:
where do I place this function...




....thus it becomes available within class "Foo" and all other Classes?

Something like a central import?

..
Good grief ...
 
G

George Sakkis

Ilias said:
I like to add a method "writeDebug(self, msg)" to all (or the most
possible) classes in the system.

How do I do this?

* with new style classes
* with old style classes

Short answer: you can't do it for builtin or extension types:....
TypeError: can't set attributes of built-in/extension type 'list'

Longer asnwer: Make it a function instead of a method. This function
could try to call the respective method, and as a fallback it would
have hardcoded what to do for each supported class, something like:

def writeDebug(obj, msg):
try: return obj.writeDebug(msg)
except AttributeError:
if isinstance(obj,list):
# list msg
elif isinstance(obj,tuple):
# tuple msg
...
else:
# default object msg

If you insist though that you'd rather not use functions but only
methods, tough luck; you're better off with Ruby.

George
 
I

Ilias Lazaridis

MonkeeSage said:
Ilias said:
where do I place this function...

The place where you want it to be.
...thus it becomes available within class "Foo" and all other Classes?

Anything defined in the top-level (i.e., the sys.modules['__main__']
namespace) is accessible in every scope...but I assume you already know
that.

no, I don't know it.

how do I define something into the top-level namespace? I assume I
could place it into the root-package of my project, into the __init__
function.

But how do I place it within my computers python installation (the big
init)?
You could also use a super-duper super class from which to derive all
your other classes, and add/replace any methods you want there:

class lazaridis(object):
....

I am aware of this technique.

But I want to modify existent classes, without touching their code.
That would probably be the most logical thing to do.

But again, I assume you already know all this, so why are you asking?
Is this part of the evaluation process?

I am not evaluating Python, I've started using it:

http://case.lazaridis.com/wiki/Lang
http://dev.lazaridis.com/base

-

I've noticed some interesting code on you website:

"
class file(file):
def reopen(self, name=None, mode='w', bufsize=None):
....

fh = file('test.txt', 'rb')
print fh # <open file 'test.txt', mode 'rb' at 0xb7c92814>
fh.reopen(mode='wb')
"
http://rightfootin.blogspot.com/2006/09/ruby-reopen.html

does this mean that I can add a method to a class in a similar way with
ruby? (by using class class-name(class-name): )

but the limitation is that I cannot do this with the python build-in
types?:

http://rightfootin.blogspot.com/2006/08/of-rocks-and-reptiles.html

..
 
M

MonkeeSage

Ilias said:
no, I don't know it.

OK...so how do you evaluate a language when you don't know its basic
operations? Hmmm, sounds fishy.
how do I define something into the top-level namespace? I assume I
could place it into the root-package of my project, into the __init__
function.

But how do I place it within my computers python installation (the big
init)?

When you just say:

def blah(): pass

Now 'blah' function is in the top-level namespace, just like global
variables. Or if it's in a different file, you'd say 'from blah import
*'. You honestly don't know this?!??
I am aware of this technique.

But I want to modify existent classes, without touching their code.

The only way to do this is to explicitly subclass the existent classes
with your own class and modify what you want there in your subclass
(see below), or use multiple inheritence as I suggested previously.
I've noticed some interesting code on you website:

"
class file(file):
def reopen(self, name=None, mode='w', bufsize=None):
...

fh = file('test.txt', 'rb')
print fh # <open file 'test.txt', mode 'rb' at 0xb7c92814>
fh.reopen(mode='wb')
"
http://rightfootin.blogspot.com/2006/09/ruby-reopen.html

does this mean that I can add a method to a class in a similar way with
ruby? (by using class class-name(class-name): )

Basically, yes. In ruby you can reopen base classes; in python you can
get the same effect by subclassing the base classes with the same name
as the base class, then instantiating all your objects as that class.
This is the exact same idea as a "super-duper super class" as I
mentioned above.
but the limitation is that I cannot do this with the python build-in
types?:

http://rightfootin.blogspot.com/2006/08/of-rocks-and-reptiles.html

You can subclass buit-in types using the same name as the parent class.
In fact here is what I use:

## my little library to make python more OO
## i.e., to get rid of the top-level junk...
## or at least to hide it behind some pretty
## object attributes :)
##
## YMMV - and don't complain if you don't
## like it; I wrote it for ME, not you
##
## Jordan Callicoat < (e-mail address removed) >

## some global methods so we can use them
## to set up the class methods
def rpr(self):
return str(repr(self))
def stri(self):
return str(self)
def inte(self):
return int(self)
def leng(self):
return int(len(self))
def say(self):
print(self)
return self
def joi(self, sep=''):
return str(sep.join(self))
def ma(self, m):
return list(map(m, self))
def filt(self, m):
return list(filter(m, self))
def redu(self, m):
return list(reduce(m, self))


## now build all the subclasses
class int(int):
"""
Wrapper class for +int+
Provided methods:
str(), int(), repr(), say(),
len(), plus(), minus(),
times(), divided_by()
"""
def plus(self, i):
return int(self + i)
def minus(self, i):
return int(self - i)
def times(self, i):
return int(self * i)
def divided_by(self, i):
return int(self / i)

int.str = stri
int.repr = rpr
int.len = leng
int.int = inte
int.say = say

class str(str):
"""
Wrapper class for +str+
Provided methods:
str(), int(), repr(), say(),
len(), plus(), times()
"""
def plus(self, s):
return str(self + s)
def times(self, i):
return str(self * i)

str.str = stri
str.repr = rpr
str.len = leng
str.int = inte
str.say = say

class list(list):
"""
Wrapper class for +list+
Provided methods:
str(), int(), repr(), say(),
len(), plus(), times(), join()
"""
def plus(self, l):
return list(self + l)
def times(self, i):
return list(self * i)

list.str = stri
list.repr = rpr
list.len = leng
list.say = say
list.join = joi
list.map = ma
list.filter = filt
list.reduce = redu

class tuple(tuple):
"""
Wrapper class for +tuple+
Provided methods:
str(), int(), repr(), say(),
len(), plus(), times(), join()
"""
def plus(self, l):
return tuple(self + l)
def times(self, i):
return tuple(self * i)

tuple.str = stri
tuple.repr = rpr
tuple.len = leng
tuple.say = say
tuple.join = joi
tuple.map = ma
tuple.filter = filt
tuple.reduce = redu

class dict(dict):
"""
Wrapper class for +dict+
Provided methods:
str(), int(), repr(), say(),
len()
"""
pass

dict.str = stri
dict.repr = rpr
dict.len = leng
dict.say = say
dict.join = joi


## done with the global methods, remove them
del(rpr, stri, inte, say, joi, ma, filt, redu)


## show examples if called standalone
if (__name__ == '__main__'):
i = int(5)
n = i + 5
n.say()
i = i.times(5).divided_by(3).plus(2)
i.str().int().str().repr().say()

s = 'Tree'
i = str(s)
i = i.plus(' and dog\n').times(2)
i.repr().say()

def test(item):
return '%s!' % item
l = ['test', 'this', 'out', 'now']
i = list(l)
i = i.times(2)
i.join(' ').say()
i.map(test).say()

t = ('test', 'this', 'out', 'now')
i = tuple(t)
i = i.plus(('hi', 'there'))
i.join('+').repr().say()
i.map(test).say()

d = {'test': 'this', 'out': 'now'}
i = dict(d)
i.len().say()

It's not the most "pythojnic" way to do things, but it works for me.

Ps. I still have a hard time belieiving that after all the time you've
spent on comp.lang.lisp, comp.lang.ruby and comp.lang.python you still
don't understand these basic concepts...if that's really true, I would
never use your consulting service!

Regards,
Jorda
 
I

Ilias Lazaridis

MonkeeSage said:
OK...so how do you evaluate a language when you don't know its basic
operations? Hmmm, sounds fishy.

The learning-process is an important part of the evaluation.
When you just say:

def blah(): pass

Now 'blah' function is in the top-level namespace, just like global
variables. Or if it's in a different file, you'd say 'from blah import
*'. You honestly don't know this?!??

I know how to define it:

--- myBlahWithImport.py ---
from mylib import blah

if (__name__ == '__main__'):
blah()
--- end file ---

what I dont know is, how to negate the need of the import statement.

--- myBlah.py ---
if (__name__ == '__main__'):
blah()
--- end file ---
The only way to do this is to explicitly subclass the existent classes
with your own class and modify what you want there in your subclass
(see below), or use multiple inheritence as I suggested previously.


Basically, yes. In ruby you can reopen base classes; in python you can
get the same effect by subclassing the base classes with the same name
as the base class, then instantiating all your objects as that class.
This is the exact same idea as a "super-duper super class" as I
mentioned above.

That's a part of the construct I was looking for.
You can subclass buit-in types using the same name as the parent class.

So, that's a 2nd part of the constrcut I was looking for.

btw: from which class does "int" inherit?
In fact here is what I use:

## my little library to make python more OO
## i.e., to get rid of the top-level junk...
## or at least to hide it behind some pretty
## object attributes :)
##
## YMMV - and don't complain if you don't
## like it; I wrote it for ME, not you
##
## Jordan Callicoat < (e-mail address removed) >

## some global methods so we can use them
## to set up the class methods
.... (many code I'll review at a later point)
It's not the most "pythojnic" way to do things, but it works for me.

Ps. I still have a hard time belieiving that after all the time you've
spent on comp.lang.lisp, comp.lang.ruby and comp.lang.python you still
don't understand these basic concepts...if that's really true, I would
never use your consulting service!


"CONSTRUCT - Adding Functionality to the Overall System"

This is not a basic concept.

Although in smaltalk and ruby is very simple.

But I've selected to use Python.

..
 
M

Michele Simionato

(I don't believe I am responding to a notorious troll ...)

One (bad) solution is to write in your sitecustomize.py the following:

$ echo /usr/lib/python/sitecustomize.py
import __builtin__

class Object(object):
def debug(self):
print 'some debug info'

__builtin__.object = Object

then you can do for instance
some debug info

All class inheriting from object will have the additional debug method.
However I DO NOT
RECOMMEND THIS SOLUTION FOR ANY SERIOUS WORK. For instance, it broke my
IPython installation and I am pretty sure it will broke other things
too.
But it may work for debugging purposes, if not for production use, so I
thought it was worth
posting.

Michee Simionato
 
S

Steve Holden

Michele said:
(I don't believe I am responding to a notorious troll ...)
Believe it. You are. Ain't life a bitch? :)
One (bad) solution is to write in your sitecustomize.py the following:

$ echo /usr/lib/python/sitecustomize.py
import __builtin__

class Object(object):
def debug(self):
print 'some debug info'

__builtin__.object = Object

then you can do for instance



some debug info

All class inheriting from object will have the additional debug method.

But sadly not the built-in types like int and str, which is what our
trollish friend wants to do (for some reason best known to himself).
However I DO NOT
RECOMMEND THIS SOLUTION FOR ANY SERIOUS WORK. For instance, it broke my
IPython installation and I am pretty sure it will broke other things
too.
But it may work for debugging purposes, if not for production use, so I
thought it was worth
posting.

regards
Steve
 
I

Ilias Lazaridis

George said:
Short answer: you can't do it for builtin or extension types:
...
TypeError: can't set attributes of built-in/extension type 'list'

Longer asnwer: Make it a function instead of a method. This function
could try to call the respective method, and as a fallback it would
have hardcoded what to do for each supported class, something like:

def writeDebug(obj, msg):
try: return obj.writeDebug(msg)
except AttributeError:
if isinstance(obj,list):
# list msg
elif isinstance(obj,tuple):
# tuple msg
...
else:
# default object msg

If you insist though that you'd rather not use functions but only
methods, tough luck; you're better off with Ruby.

I insist on methods, and It seems that I stay with Python.

The effort for me to rework python to become more OO is much lesser,
than the effort I would have to rework Ruby to become more (this and
that).

http://case.lazaridis.com/wiki/Lang

And I've already started to like 2 things on python:

* the missing "end" statement and
* (I don't believe I write this) enforced indentation.

..
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top