473,473 Members | 1,977 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Storing objects required by functions.

Further to my last post here, I was playing some more with building a
regex object and storing it somewhere for use internally by a
function. I'm not happy with any of my solutions:
# I don't like this, but the fact that you can modify the procedure's
# function via a named argument seems neat in a hacky sort of way.

def uses_default_parm_yuck(x, r = re.compile("...")):
pass
g = re.compile('...')

def uses_global_yuck(x):
global g
pass
# This is horrible and probably slow.

class is_hex:
def __init__(self):
self.r = re.compile('...')

def __call__(self, x):
r = self.r
pass

is_hex = is_hex()
# This mucks up scoping so that your procedure can't access it's
# parent scope like it could normally. Since I never do this,
# it's my favourite.

def is_hex():
r = re.compile('...')
def is_hex(s):
return r.match(s) is not None
return is_hex

is_hex = is_hex()

Am I missing something? Is there a nicer way of doing this? On a day
to day basis I find myself in this situation quite regularly, and now
I come to think of it today, it is something that I would like to
improve.

It is funny that in private it has never bothered me much, but when
posting on comp.lang.python I find that the code is unacceptable.
Maybe I have two modes of programming, idealist and practical? *shrug*
:)
David.
Jul 18 '05 #1
14 1308

"David M. Wilson" <dw***********@botanicus.net> wrote in message
news:99**************************@posting.google.c om...
Further to my last post here, I was playing some more with building a
regex object and storing it somewhere for use internally by a
function. I'm not happy with any of my solutions:
# I don't like this, but the fact that you can modify the procedure's
# function via a named argument seems neat in a hacky sort of way.

def uses_default_parm_yuck(x, r = re.compile("...")):
pass
g = re.compile('...')

def uses_global_yuck(x):
global g
pass
# This is horrible and probably slow.

class is_hex:
def __init__(self):
self.r = re.compile('...')

def __call__(self, x):
r = self.r
pass

is_hex = is_hex()
# This mucks up scoping so that your procedure can't access it's
# parent scope like it could normally. Since I never do this,
# it's my favourite.

def is_hex():
r = re.compile('...')
def is_hex(s):
return r.match(s) is not None
return is_hex

is_hex = is_hex()

Am I missing something? Is there a nicer way of doing this? On a day
to day basis I find myself in this situation quite regularly, and now
I come to think of it today, it is something that I would like to
improve.

It is funny that in private it has never bothered me much, but when
posting on comp.lang.python I find that the code is unacceptable.
Maybe I have two modes of programming, idealist and practical? *shrug*
:)
Your second solution (the one you labeled "horrible and probably
slow") is a classic example of a Function Object, and it's described
that way in "Design Patterns". AFAIK, it's got the same call overhead
as any other way of doing the job. I'd call it the cleanest way of doing
a parameterized function.

John Roth

David.

Jul 18 '05 #2
In article <99**************************@posting.google.com >,
David M. Wilson <dw***********@botanicus.net> wrote:

g = re.compile('...')

def uses_global_yuck(x):
global g
pass


Why not just use the global? Without the ``global`` statement, that is.
Don't like that? How's it any different from using a class instance?
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

Weinberg's Second Law: If builders built buildings the way programmers wrote
programs, then the first woodpecker that came along would destroy civilization.
Jul 18 '05 #3

"Aahz" <aa**@pythoncraft.com> wrote in message
news:bs**********@panix1.panix.com...
In article <99**************************@posting.google.com >,
David M. Wilson <dw***********@botanicus.net> wrote:

g = re.compile('...')

def uses_global_yuck(x):
global g
pass
Why not just use the global? Without the ``global`` statement, that is.
Don't like that? How's it any different from using a class instance?


You can't parameterize it. You've got one global, while
you can put different parameters in different class instances.
He isn't doing that here, but that's the major place where the
Function Object design pattern shines.

John Roth
--
Aahz (aa**@pythoncraft.com) <*>

http://www.pythoncraft.com/
Jul 18 '05 #4
David M. Wilson wrote:
Further to my last post here, I was playing some more with building a
regex object and storing it somewhere for use internally by a
function. I'm not happy with any of my solutions:
# I don't like this, but the fact that you can modify the procedure's
# function via a named argument seems neat in a hacky sort of way.

def uses_default_parm_yuck(x, r = re.compile("...")):
pass
g = re.compile('...')

def uses_global_yuck(x):
global g
pass

There is no need to define g as global unless you actually need to
rebind g inside the function.

# This is horrible and probably slow.

class is_hex:
def __init__(self):
self.r = re.compile('...')

def __call__(self, x):
r = self.r
pass

is_hex = is_hex()

I doubt it's that much slower (if at all). You should profile it to check.

# This mucks up scoping so that your procedure can't access it's
# parent scope like it could normally. Since I never do this,
# it's my favourite.

def is_hex():
r = re.compile('...')
def is_hex(s):
return r.match(s) is not None
return is_hex

is_hex = is_hex()

Am I missing something? Is there a nicer way of doing this? On a day
to day basis I find myself in this situation quite regularly, and now
I come to think of it today, it is something that I would like to
improve.

It is funny that in private it has never bothered me much, but when
posting on comp.lang.python I find that the code is unacceptable.
Maybe I have two modes of programming, idealist and practical? *shrug*
:)
David.


Another alternative relies on the fact that functions themselves are
objects so you could do this:

def is_hex(s):
return is_hex.r.match(s) is not None

is_hex.r = re.compile(...)
Although, for simplicity, I would probably just make the compiled regex
a module scope variable with a sensible name, maybe even using the _
prefix to hint that noone should touch it:

_is_hex_regex = re.compile(...)

def is_hex(s):
return _is_hex_regex.match(s) is not None
Cheers, Matt

--
Matt Goodall, Pollenation Internet Ltd
w: http://www.pollenationinternet.com
e: ma**@pollenation.net

Jul 18 '05 #5

"David M. Wilson" <dw***********@botanicus.net> wrote in message
news:99**************************@posting.google.c om...
Further to my last post here, I was playing some more with building a
regex object and storing it somewhere for use internally by a
function. I'm not happy with any of my solutions: # I don't like this, but the fact that you can modify the procedure's
# function via a named argument seems neat in a hacky sort of way.

def uses_default_parm_yuck(x, r = re.compile("...")):
pass
I default args less bothersome than some people. The only problem for me
is that a caller may accidentally give nonesense second param. If this can
silently give a junk answer, this is not very acceptable. In this case,
random objects without a match() method would raise an exception.
g = re.compile('...')
Use _ to indicate 'private' or 'local-use-only' status.

_hex = re.compile()
def uses_global_yuck(x):
global g
pass
The global declaration is not needed for read-only access and is therefore
misleading. So delete and just use _hex in the body. Python functions
constantly use globals and builtins, both functions and other values, in
read-only mode. So I see no problem with this standard Python idiom.
# This is horrible and probably slow.

class is_hex:
def __init__(self):
self.r = re.compile('...')

def __call__(self, x):
r = self.r
pass
One should at least generalize this to re_matcher and pass specific re to
init. OO purists might prefer this but I agree that it is overkill unless,
possibly, one has lots of instances. OO was made for man, not man for OO
purity.
is_hex = is_hex()
is_hex = re_matcher(hex_re)
# This mucks up scoping so that your procedure can't access it's
# parent scope like it could normally.
Funny, you just objected above to having a function access is parent scope
for the re.
def is_hex():
r = re.compile('...')
def is_hex(s):
return r.match(s) is not None
return is_hex is_hex = is_hex()


Same comment: generalize

def re_matcher(some_re):
r = re.compile(some_re)
def is_some(s):
return r.match(s) is not None
return is_some

is_hex = re_matcher(hex_re)

I would use this in preverence to class version for making multiple
matchers. I think closures are great as one-method instances (or as
callable no-method instances, if one prefers).

Terry J. Reedy
Jul 18 '05 #6
On Tue, Dec 30, 2003 at 12:43:13PM -0500, Terry Reedy wrote:

I default args less bothersome than some people. The only problem for me
is that a caller may accidentally give nonesense second param. If this can
silently give a junk answer, this is not very acceptable. In this case,
random objects without a match() method would raise an exception.
g = re.compile('...')


Use _ to indicate 'private' or 'local-use-only' status.

_hex = re.compile()


Why should it be local-use-only?

Jp

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQE/8dMYedcO2BJA+4YRAgWbAJwNC9zferduRJarhPQbRBltnJWw9g CglSJA
c/gKhA2op4Y7Sg43ugSdG+A=
=ku9c
-----END PGP SIGNATURE-----

Jul 18 '05 #7
Could you please *not* add whatever signature or business
card or whatever you're adding to your messages? My anti-virus
blocks access to your entire message when you do that,
and it's a royal pain to save the message and then disassemble
it to find you made one line of comment.

John Roth

"Jp Calderone" <ex*****@intarweb.us> wrote in message
news:ma************************************@python .org...
Jul 18 '05 #8
On Tue, Dec 30, 2003 at 03:22:09PM -0500, John Roth wrote:
Could you please *not* add whatever signature or business
card or whatever you're adding to your messages? My anti-virus
blocks access to your entire message when you do that,
and it's a royal pain to save the message and then disassemble
it to find you made one line of comment.

John Roth

"Jp Calderone" <ex*****@intarweb.us> wrote in message
news:ma************************************@python .org...


It's a PGP signature. If the mail client you're using can't extricate the
plaintext part, I'd say it isn't a very good mail client. (Even mailman's
archiver deals with them the right way these days ;)

Jp

Jul 18 '05 #9
On 30 Dec 2003 06:55:27 -0800, dw***********@botanicus.net (David M. Wilson) wrote:
Further to my last post here, I was playing some more with building a
regex object and storing it somewhere for use internally by a
function. I'm not happy with any of my solutions:
# I don't like this, but the fact that you can modify the procedure's
# function via a named argument seems neat in a hacky sort of way.

def uses_default_parm_yuck(x, r = re.compile("...")):
pass
There is another way, but IMO it would be nice to be able to have an optional
second parenthesized list to make bindings the same way which wouldn't be part
of the call signature. I.e.,

def uses_default_parm_yuck(x)(r = re.compile("...")):
pass

or, same thing more prominently:

def uses_default_parm_yuck(x)(
# pre-bound locals
r = re.compile("...")
):
pass

ISTM most of the implementation pieces for that should already be there.

The other way is to take advantage of functions' roles as decriptors and the mechanism that
makes bound methods with a self as the first arg, but the rest apparently normal. I.e,
we can put the r parameter in the place of self (not specifically tested)

def uses_self(r, x):
pass
uses_self = uses_self.__get__(re.compile("..."))

then (the rebound) uses_self will look like a bound method and want exactly one parameter x
(or whatever signature you program) and be able to refer to r like self.

g = re.compile('...')

def uses_global_yuck(x):
global g
pass
# This is horrible and probably slow.

class is_hex:
def __init__(self):
self.r = re.compile('...')

def __call__(self, x):
r = self.r
pass

is_hex = is_hex()
# This mucks up scoping so that your procedure can't access it's
# parent scope like it could normally. Since I never do this,
# it's my favourite.

def is_hex():
r = re.compile('...')
def is_hex(s):
return r.match(s) is not None
return is_hex

is_hex = is_hex()

Am I missing something? Is there a nicer way of doing this? On a day
to day basis I find myself in this situation quite regularly, and now
I come to think of it today, it is something that I would like to
improve.

It is funny that in private it has never bothered me much, but when
posting on comp.lang.python I find that the code is unacceptable.
Maybe I have two modes of programming, idealist and practical? *shrug*
:)
David.


Regards,
Bengt Richter
Jul 18 '05 #10

"Jp Calderone" <ex*****@intarweb.us> wrote in message
news:ma************************************@python .org...
On Tue, Dec 30, 2003 at 03:22:09PM -0500, John Roth wrote:
Could you please *not* add whatever signature or business
card or whatever you're adding to your messages? My anti-virus
blocks access to your entire message when you do that,
and it's a royal pain to save the message and then disassemble
it to find you made one line of comment.

John Roth

"Jp Calderone" <ex*****@intarweb.us> wrote in message
news:ma************************************@python .org...

It's a PGP signature. If the mail client you're using can't extricate

the plaintext part, I'd say it isn't a very good mail client. (Even mailman's
archiver deals with them the right way these days ;)
Actually, whatever is doing it simply sequesters almost anything,
including perfectly innocuous graphics. The difficulty is that the
mail client still displays most of the sequestered attachments, but
for some reason if it can't figure out one attachment, it doesn't
display any of them.

That means I've got to save the entire mail and use a command line
tool to break it into pieces. Python's mail tools do a reasonable
(not excellent) job of this, so nothing is lost, but it's more work
than I usually want to go through for newsgroup messages.

John Roth


Jp

Jul 18 '05 #11
On 31 Dec 2003 00:08:47 GMT, rumours say that bo**@oz.net (Bengt
Richter) might have written:
The other way is to take advantage of functions' roles as decriptors and the mechanism that
makes bound methods with a self as the first arg, but the rest apparently normal. I.e,
we can put the r parameter in the place of self (not specifically tested)

def uses_self(r, x):
pass
uses_self = uses_self.__get__(re.compile("..."))


It's much more general to use new.instancemethod. See:

def voodoo(function, *its_arguments):
from new import instancemethod
def child(function, first_argument, *rest_of_arguments):
if rest_of_arguments:
return child(
instancemethod(function, first_argument, object),
*rest_of_arguments
)
else:
return instancemethod(function, first_argument, object)
return child(function, *its_arguments)

The import statement is in the voodoo just for completeness including it
here.
The function above recurses in order to allow stuff like:

getter = voodoo(getattr, my_object, "its_attribute")

or the more modern

getter = voodoo(operator.itemgetter("its_attribute"), my_object)

and similarly

setter = voodoo(operator, my_object, "its_attribute")

allowing

setter(value)

at good speeds.
I have a module predicates.py defining All and Any classes for
iterables, and the trick above plus itertools allows *some* operations
to run faster than correspondent python code...
--
TZOTZIOY, I speak England very best,
Ils sont fous ces Redmontains! --Harddix
Jul 18 '05 #12
On Wed, 31 Dec 2003 04:04:47 +0200, Christos "TZOTZIOY" Georgiou <tz**@sil-tec.gr> wrote:
On 31 Dec 2003 00:08:47 GMT, rumours say that bo**@oz.net (Bengt
Richter) might have written:
The other way is to take advantage of functions' roles as decriptors and the mechanism that
makes bound methods with a self as the first arg, but the rest apparently normal. I.e,
we can put the r parameter in the place of self (not specifically tested)

def uses_self(r, x):
pass
uses_self = uses_self.__get__(re.compile("..."))
It's much more general to use new.instancemethod. See:

I think I did use new.instancemethod, through another door ;-)
def uses_self(r, x): ... pass
... import re
uses_self = uses_self.__get__(re.compile("..."))
type(uses_self) <type 'instancemethod'>
myim = type(uses_self)
myim <type 'instancemethod'>
import new
myim is new.instancemethod True
;-)
def foo(self, *args, **kw): print 'self=%r, args=%r, kw=%r'%(self, args, kw) ... myim(foo, 'dummy self', object) # object per your usage <bound method object.foo of 'dummy self'> foom = myim(foo, 'dummy self', object) # object per your usage
foom(1,2,3,hi='Hello')

self='dummy self', args=(1, 2, 3), kw={'hi': 'Hello'}

I didn't make voodoo out of it though. Interesting, but all that nested
calling at call-time seems like it would make for a performance hit? Unless maybe it is
all packed up in slots that C can get to very fast??

def voodoo(function, *its_arguments):
from new import instancemethod
def child(function, first_argument, *rest_of_arguments):
if rest_of_arguments:
return child(
instancemethod(function, first_argument, object),
*rest_of_arguments
)
else:
return instancemethod(function, first_argument, object)
return child(function, *its_arguments)

The import statement is in the voodoo just for completeness including it
here.
The function above recurses in order to allow stuff like:

getter = voodoo(getattr, my_object, "its_attribute")

or the more modern

getter = voodoo(operator.itemgetter("its_attribute"), my_object)

and similarly

setter = voodoo(operator, my_object, "its_attribute")

allowing

setter(value)

at good speeds.
I have a module predicates.py defining All and Any classes for
iterables, and the trick above plus itertools allows *some* operations
to run faster than correspondent python code...

Interesting. Gotta go.

Regards,
Bengt Richter
Jul 18 '05 #13
On 31 Dec 2003 04:07:01 GMT, rumours say that bo**@oz.net (Bengt
Richter) might have written:
It's much more general to use new.instancemethod. See:
I think I did use new.instancemethod, through another door ;-)


No doubt :) . *I* wasn't clear: new.instancemethod accepts any callable
I throw to it, while not all callables have a __get__ method...
foom(1,2,3,hi='Hello')

self='dummy self', args=(1, 2, 3), kw={'hi': 'Hello'}

I didn't make voodoo out of it though. Interesting, but all that nested
calling at call-time seems like it would make for a performance hit? Unless maybe it is
all packed up in slots that C can get to very fast??


Actually, I think that most overhead lies in creating a frame object for
the execution of a python callable. Calling C functions is fastest. I
didn't spot any delays, but I didn't search thoroughly ;)
--
TZOTZIOY, I speak England very best,
Ils sont fous ces Redmontains! --Harddix
Jul 18 '05 #14
In article <ma************************************@python.org >,
Jp Calderone <ex*****@intarweb.us> wrote:

It's a PGP signature. If the mail client you're using can't extricate the
plaintext part, I'd say it isn't a very good mail client. (Even mailman's
archiver deals with them the right way these days ;)


I'm using netnews, not e-mail. PGP doesn't belong in netnews posts, IMO.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

Weinberg's Second Law: If builders built buildings the way programmers wrote
programs, then the first woodpecker that came along would destroy civilization.
Jul 18 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Ann Huxtable | last post by:
Hi, I am writing a nested table structure to mimic data returned from a database (actually, a heirarchical recordset). I am representing the cells where the actual data is stored, by a union:...
6
by: Alfonso Morra | last post by:
I have written the following code, to test the concept of storing objects in a vector. I encounter two run time errors: 1). myClass gets destructed when pushed onto the vector 2). Prog throws a...
22
by: Wynand Winterbach | last post by:
I think every C programmer can relate to the frustrations that malloc allocated arrays bring. In particular, I've always found the fact that the size of an array must be stored separately to be a...
1
by: Együd Csaba | last post by:
Hi All, I use PG 7.3.2 an 7.4.1 on RH 7.1. I'd like to store small (~ 100x100 px jpeg, or gif) images in a field in binary format. I tried to understand the documentation of the large objects but...
2
by: nacho222 | last post by:
I'm currently in the middle of writing a persistence framework, and I have to make a design decission. The framework will take care of all the saving and restoring objects, and also the...
10
by: Mark Rae | last post by:
Hi, This relates to the previous thread "Disappearing Sessions", but is a bit more generic so I thought I'd start a new thread. This one relates to the storing of objects in Session once only to...
3
by: RSH | last post by:
Hi, I have a situation where I have created an object that contains fields,properties and functions. After creating the object I attempted to assign it to a session variable so i could retrieve...
3
by: mk | last post by:
Hello everyone, I'm storing functions in a dictionary (this is basically for cooking up my own fancy schmancy callback scheme, mainly for learning purpose): .... return "f2 " + arg .......
0
by: Calvin Spealman | last post by:
On Thu, Jul 17, 2008 at 7:45 AM, mk <mrkafk@gmail.comwrote: As was pointed out already, this is a basic misunderstanding of assignment, which is common with people learning Python. To your...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
muto222
php
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.