NEWBIE: What's the instance name?

E

engsolnom

Hi,
I've been using constructs(?) like the below.

def display(instance, start = None, end = None):

if instance.__class__.__name__ == 'UPCA':
do some UPCA stuff
if instance.__class__.__name__ == 'UPCE':
do some UPCE stuff

launched by:

lx = UPCA(sx), where sx is a string
then:
display(lx)

This all works well.

What I'd like to do is display is the instance name. Is it hiding
somewhere?

Also, if I have a string 4 chars long, representing two bytes of hex,
how can I *validate* the string as a *legal* hex string?

isdigit works until string = '001A', for example
isalnum works, but then allows 'foob'

Is there a 'ishexdigit'? I could parse the string, but that seems
"un-Pythonish"

Thanks in advane....Norm
 
J

John Roth

Hi,
I've been using constructs(?) like the below.

def display(instance, start = None, end = None):

if instance.__class__.__name__ == 'UPCA':
do some UPCA stuff
if instance.__class__.__name__ == 'UPCE':
do some UPCE stuff

launched by:

lx = UPCA(sx), where sx is a string
then:
display(lx)

This all works well.

What I'd like to do is display is the instance name. Is it hiding
somewhere?

Also, if I have a string 4 chars long, representing two bytes of hex,
how can I *validate* the string as a *legal* hex string?

isdigit works until string = '001A', for example
isalnum works, but then allows 'foob'

Is there a 'ishexdigit'? I could parse the string, but that seems
"un-Pythonish"

Thanks in advane....Norm

Instances don't have names. They do have IDs, though, which are
the memory address of the instance objects in the
C Python implementation. See the built-in function id().

John Roth
 
B

Ben Finney

Also, if I have a string 4 chars long, representing two bytes of hex,
how can I *validate* the string as a *legal* hex string?

isdigit works until string = '001A', for example
isalnum works, but then allows 'foob'

Is there a 'ishexdigit'? I could parse the string, but that seems
"un-Pythonish"

More Pythonish is to use string.hexdigits and map() to write your own:
... result = ( char in string.hexdigits )
... return result
... ... resultmap = map( ishexdigit, str )
... result = ( False not in resultmap )
... return result
... False
 
P

Paul Rubin

What I'd like to do is display is the instance name. Is it hiding
somewhere?

You mean the name of variable where that the instance is bound to? No.
Also, if I have a string 4 chars long, representing two bytes of hex,
how can I *validate* the string as a *legal* hex string?

isdigit works until string = '001A', for example
isalnum works, but then allows 'foob'

Is there a 'ishexdigit'? I could parse the string, but that seems
"un-Pythonish"

Just import string and use "d in string.hexdigits".
 
B

Ben Finney

What I'd like to do is display is the instance name. Is it hiding
somewhere?

What does "the instance name" mean when several names are bound to the
same instance?
 
D

David M. Wilson

(e-mail address removed) wrote...
Also, if I have a string 4 chars long, representing two bytes of hex,
how can I *validate* the string as a *legal* hex string?

isdigit works until string = '001A', for example
isalnum works, but then allows 'foob'

Is there a 'ishexdigit'? I could parse the string, but that seems
"un-Pythonish"


Have you considered using the int() builtin? Here is an example:

def is_hex(n):
'''
Return truth if <n> can be converted as hexadecimal
from a string.
'''

try:
int(n, 16)
return True

except ValueError:
return False
 
B

Bengt Richter

(e-mail address removed) wrote...



Have you considered using the int() builtin? Here is an example:

def is_hex(n):
'''
Return truth if <n> can be converted as hexadecimal
from a string.
'''

try:
int(n, 16)
return True

except ValueError:
return False

But that will accept '0x55' which I doubt the OP will like ;-)

If you don't care about speed,
(Not tested beyond what you see ;-)
>>> def isHex(n): return bool(min([c in '0123456789ABCDEFabcdef' for c in n])) ...
>>> isHex('005') True
>>> isHex('0x5') False
>>> isHex('0123456789ABCDEFabcdef') True
>>> isHex('0123456789ABCDEFabcdefg')
False

Probably faster, depending on the C implementation:
... return not s.translate(
... '................................'
... '................................'
... '................................'
... '................................'
... '................................'
... '................................'
... '................................'
... '................................',
... '0123456789ABCDEFabcdef')
... True



Regards,
Bengt Richter
 
P

Paul McGuire

Hi,
I've been using constructs(?) like the below.

def display(instance, start = None, end = None):

if instance.__class__.__name__ == 'UPCA':
do some UPCA stuff
if instance.__class__.__name__ == 'UPCE':
do some UPCE stuff

launched by:

lx = UPCA(sx), where sx is a string
then:
display(lx)
Why don't you just define a display() method on the UPCA and UPCE classes,
and instead of display(lx), call lx.display(). If UPCA and UPCE inherit
from a common base class (presumably with an abstract or default display()
method, but not necessarily), this is called "polymorphism".

Something like this:

class StringDisplayer(object):
def __init__(instance, instring ):
instance.dispString = instring

class UPCA(StringDisplayer):
def display(instance, start = None, end = None):
# UPCA-specific display stuff goes here

class UPCE(StringDisplayer):
def display(instance, start = None, end = None):
# UPCE-specific display stuff goes here

sx = "abc"
lx = UPCA(sx)
lx.display()

Your example also uses "instance" for the pointer to self, which works okay,
but is non-traditional; the conventional name for the self pointer is
"self".

In general, any time you are if-testing on the class of an object, you are
probably doing something polymorphic. If there is common behavior also, put
this in the base StringDisplayer class, and invoke it using
"super(UPCA,instance).display()" in the display() method of the UPCA class,
and likewise in the UPCE class.
 
D

Dan Bishop

Hi,
I've been using constructs(?) like the below.

def display(instance, start = None, end = None):
if instance.__class__.__name__ == 'UPCA':

You might want to try the isinstance function.
do some UPCA stuff
if instance.__class__.__name__ == 'UPCE':
do some UPCE stuff

launched by:

lx = UPCA(sx), where sx is a string
then:
display(lx)

This all works well.

What I'd like to do is display is the instance name. Is it hiding
somewhere?

You mean you'd like display(lx) to print "lx"?

What would you expect the folowing code to do?

a = b = MyClass()
display(a) # "a" or "b"?
display(a + b) # Creates an instance without a name.
display(2) # Literals have no names either.

Now do you see why the functionality you want isn't implemented?
Also, if I have a string 4 chars long, representing two bytes of hex,
how can I *validate* the string as a *legal* hex string?

isdigit works until string = '001A', for example
isalnum works, but then allows 'foob'

Is there a 'ishexdigit'? I could parse the string, but that seems
"un-Pythonish"

Unfortunately, no, but you can use "ch in string.hexdigits", at least
until Python 3.0 (or whenever the string module is going away).
 
A

Alan Gauld

I've been using constructs(?) like the below.

def display(instance, start = None, end = None):
if instance.__class__.__name__ == 'UPCA':
do some UPCA stuff
if instance.__class__.__name__ == 'UPCE':
do some UPCE stuff

launched by:

lx = UPCA(sx), where sx is a string
then:
display(lx)

Any reason not to use an OO style and do:

lx = UPCA(sx)
lx.display()

That way you miss out all those horrible if instance... checks.
Its much easier to maintain too since if you add a new class you
only need write a display method in the class, you don;t need to
extend the if/elif chain too.
What I'd like to do is display is the instance name. Is it hiding
somewhere?

What is the instance's name? It is an object referenced by a
variable(or maybe by several variables...). Unless you have
defined a name attribute then the instance has no name.
Also, if I have a string 4 chars long, representing two bytes of hex,
how can I *validate* the string as a *legal* hex string?

hexdigit = "-0123456789abcdefABCDEF"
def ishexdigit(n): return 0 not in [x in hexdigit for x in n]

Not fast but it should work...
Is there a 'ishexdigit'? I could parse the string, but that seems
"un-Pythonish"

How else would ishexdigit work? :)

Alan G.

Author of the Learn to Program website
http://www.freenetpages.co.uk/hp/alan.gauld
 
B

Bengt Richter

You might want to try the isinstance function.

<nit>

That's the usual idiom, but it should be noted that
it's not exactly the same, e.g.,
False

That last, again, is not the same as True

</nit>

Regards,
Bengt Richter
 
P

Peter Otten

Bengt said:
<nit>

That's the usual idiom, but it should be noted that
it's not exactly the same, e.g.,

False

That last, again, is not the same as
True

</nit>

A few more lines to the fine print:

If you care about the class at all (and I think most of the time you
shouldn't) then compare classes, not names:

instance.__class__ == Class
instance.__class__ is Class


Peter
 
M

Michael Hudson

What I'd like to do is display is the instance name. Is it hiding
somewhere?

From http://www.amk.ca/quotations/python-quotes/page-8.html:

The same way as you get the name of that cat you found on your
porch: the cat (object) itself cannot tell you its name, and it
doesn't really care -- so the only way to find out what it's
called is to ask all your neighbours (namespaces) if it's their
cat (object)...

....and don't be surprised if you'll find that it's known by many
names, or no name at all!

-- Fredrik Lundh, 3 Nov 2000, in answer to the question "How can I
get the name of a variable from C++ when I have the PyObject*?"

One of my favourite Python quotes...

Cheers,
mwh
 
E

engsolnom

Why don't you just define a display() method on the UPCA and UPCE classes,
and instead of display(lx), call lx.display(). If UPCA and UPCE inherit
from a common base class (presumably with an abstract or default display()
method, but not necessarily), this is called "polymorphism".

Something like this:

class StringDisplayer(object):
def __init__(instance, instring ):
instance.dispString = instring

class UPCA(StringDisplayer):
def display(instance, start = None, end = None):
# UPCA-specific display stuff goes here

class UPCE(StringDisplayer):
def display(instance, start = None, end = None):
# UPCE-specific display stuff goes here

sx = "abc"
lx = UPCA(sx)
lx.display()

Your example also uses "instance" for the pointer to self, which works okay,
but is non-traditional; the conventional name for the self pointer is
"self".

In general, any time you are if-testing on the class of an object, you are
probably doing something polymorphic. If there is common behavior also, put
this in the base StringDisplayer class, and invoke it using
"super(UPCA,instance).display()" in the display() method of the UPCA class,
and likewise in the UPCE class.

Thanks to all for the good responses to my original post.

A couple of comments....

After thinking about it, (right after hitting enter, of course), I
concluded I can not 'discover' the name of the instance, for the same
reason that if x = 10, I can't ask '10' what the name of its reference
is. It simply doesn't know, and, as one responder pointed out, doesn't
care . All your replies confirmed this.

As to the (good) suggestions I use :

lx = UPCA(<string>)
lx.display()

I considered this approach. The reason I rejected it is that the
actual program has a total of 13 UPCA-like classes (different names,
of course). In use, each class may have one or many instances at a
time, as determined by the user script. My idea was to include the
calling instance 'name' in the display ...not strictly needed, but a
nice touch.

I could use:
display(lx, 'lx')
I'm thinking about this...it'd be a user option to include the 'lx'.

Why the display in the first place? The user *may* desire to display
the class output, probably most often while trouble-shooting a user
script problem.

Some of the classes have a common (or near common) display routine,
others are totally different. If I use lx.display(), the display code
has to be contained as a method in each class. I chose, for ease of
maintenance, to make a display module with all the display routines
gathered together in one spot. . In the event a future programmer
decided to make a change to the display routine for a given class, or
needed to add a class/display, I feel there's less chance of his/her
messing up the UPCA-like classes. I guess I'm a believer in
classes/methods doing a limited number of things, and doing them well.
Is that a C hang-over?

A thought:
Another idea might be to make a display base class, and inherit the
proper display method in each UPCA-like class. But that still leaves
the problem of passing the instance name to the display method.

As to the 'ishexdigit' question, thanks for suggested
approaches...lots of meat there for this newbie to bread-board and try
out.

Norm
 
A

Alan Gauld

As to the (good) suggestions I use :

lx = UPCA(<string>)
lx.display()

I considered this approach. The reason I rejected it is that the
actual program has a total of 13 UPCA-like classes (different names,
of course).

So you have an inheritance heirarchy?

In use, each class may have one or many instances at a
time, as determined by the user script. My idea was to include the
calling instance 'name' in the display ...not strictly needed, but a
nice touch.

I could use:
display(lx, 'lx')

So you could add a name parameter to the method and do:

lx.display('lx')
Why the display in the first place? The user *may* desire to display
the class output, probably most often while trouble-shooting a user
script problem.

Some of the classes have a common (or near common) display routine,

So OOP to the rescue and only write it once at the appropriately
common point in the inheritance heirarchy.
others are totally different.

And override it for the unique cases.
If I use lx.display(), the display code has to be contained as a
method in each class.

Which is good becausae if the data in the class changes you
can change the display method (or add a new override if it
was using a common one) at the same time in the same place.
The display method is tightly coupled to the internals of
the class so should be kept with the class.
I chose, for ease of maintenance, to make a display module
with all the display routines gathered together in one spot.

In fact that will almost certainly make it harder to maintain,
because the most likely need to change a display method is
because the class itself has changed. Now you have to change the
class and change the display in a separate place. And if the
class programmer forgets to change display after making a change
it breaks! This is exactly the kind of maintenance scenario that
OOP tries to avoid

[Note: if you want to change how the display occurs(eg from
terminal to GUI) then the best way is to get display to return a
string which you can then externally write to console or text
widget as needed. In fact if this is for debugging you may want
to look at providing a custom repr() method. repr() is intended
for giving a programmers view and returns a string. Then you
can dosplay your classes at the >>> prompt too for free.]
needed to add a class/display, I feel there's less chance of his/her
messing up the UPCA-like classes.

Addimng a class is no problem since he could add a new display
method. EXtending an existing class should be done by inheritance
so that the origibnal code is not affected, and will simply
extend the display method...

class UPCA:
def display(self, name = ''):
# do it here

class newUCPA(UCPA):
def __init__(self, foo):
UCPA.__init__(self)
self.foo = foo
def display(self, name = '')
UCPA.display(self,name)
print self.foo
I guess I'm a believer in classes/methods doing a limited number of things,
and doing them well.

Classes should manage their own data and that includes displayig
it if thats whats neeed. The minute you introduce extermnal
functions which access the innards of a class you have broken the
data hiding metaphor of OOP and introduced potential for
corruption of the data...
Is that a C hang-over?

Probably! :)
Another idea might be to make a display base class, and inherit the
proper display method in each UPCA-like class. But that still leaves
the problem of passing the instance name to the display method.

You could use a mixin style (which is what you propose) but it
buys very little here. If your aim is to display the internal
data of the class then the class itself should do it, its the
only one who should know whats inside, to the rest of the world
(including the inherited display class) it should be a black box.

Alan G


Author of the Learn to Program website
http://www.freenetpages.co.uk/hp/alan.gauld
 
G

Gabriel Genellina

Some of the classes have a common (or near common) display routine,
others are totally different. If I use lx.display(), the display code
has to be contained as a method in each class. I chose, for ease of
maintenance, to make a display module with all the display routines
gathered together in one spot. . In the event a future programmer
decided to make a change to the display routine for a given class, or
needed to add a class/display, I feel there's less chance of his/her
messing up the UPCA-like classes. I guess I'm a believer in
classes/methods doing a limited number of things, and doing them well.
Is that a C hang-over?

You could define anyway a display() method in each class, and delegate the
implementation to another module:

class UPCE(UPCA):
def display(self):
othermodule.display_nice_upce_instances_as_I_know_how_to_do_that(self)

class UPCF(UPCA):
def display(self):
othermodule.call_another_display_function(self)


Gabriel Genellina
Softlab SRL
 
D

David M. Wilson

(e-mail address removed) (Bengt Richter) wrote...
But that will accept '0x55' which I doubt the OP will like ;-)

I should really learn to try my own code out on some inputs before
posting. :)

Another alternative for doing this test is a regular expression.. one
of the few times I would actually use them:

def is_hex(s):
return re.match('^[a-fA-F0-9]{4}$', s) is not None

Using a compiled regex would be faster, but since I can't currently
figure out a way of storing such an 'implementation internal' object
without using a global, callable instance, or default argument, I'm
not going do it that way. :)


David.
 
T

Tim Roberts

Ben Finney said:
More Pythonish is to use string.hexdigits and map() to write your own:

... result = ( char in string.hexdigits )
... return result
...
... resultmap = map( ishexdigit, str )
... result = ( False not in resultmap )
... return result
...
False

Well, more Pythonish yet is to avoid the extraneous local variables, avoid
the use of a type as a parameter name, and use as many little-used builtins
as possible:

def ishexdigit(char):
return char in string.hexdigits

def ishexstring(strng):
return filter(ishexdigit, strng) == strng
 
U

Uwe Schmitt

Tim Roberts said:
Well, more Pythonish yet is to avoid the extraneous local variables, avoid
the use of a type as a parameter name, and use as many little-used builtins
as possible:
....

def ishexstring(strng):
return filter(ishexdigit, strng) == strng

better/faster/more pythonic:

return reduce(lambda a,b: a and ishexdigit(b), strng, True)

Greetings, Uwe
 
D

David M. Wilson

Uwe Schmitt said:
better/faster/more pythonic:

return reduce(lambda a,b: a and ishexdigit(b), strng, True)


How is it better, or faster, or more Pythonic? The only thing I can
see here that is 'more Pythonic' is blatant iterator abuse, which does
nothing for the readability or efficiency of the code. :)

What happened to good old fashioned functions, eh?

def is_hex(s, (z,n,a,f) = map(ord, '09af')):
for c in s:
o = ord(c) | 32 # OR lowercase bit.
if not (( o >= z and o <= n ) or ( o >= a and o <= f )):
return False

return True


This could of course be improved upon too. For:

profile.run("[ func('CAFEBABEAAAABBBBCCCCDDDDEEEEFFFF') \
for x in xrange(500000) ]")
profile.run("[ func('CAFEBABEAAAABBBBCCCCDDDDEEEEFXFF') \
for x in xrange(100000) ]")
profile.run("[ func('CAFEXABEAAAABBBBCCCCDDDDEEEEFXFF') \
for x in xrange(100000) ]")


The iterative version looked like this:

32500002 function calls in 227.260 CPU seconds
6300002 function calls in 42.990 CPU seconds
3800002 function calls in 26.700 CPU seconds


The 'grass roots' version looked like this:

500002 function calls in 21.090 CPU seconds
100002 function calls in 3.810 CPU seconds
100002 function calls in 1.770 CPU seconds


Sometimes I really wonder as to whether Python gets it poorly
performing name from it's implementation or it's 'standard' idioms. :)

Greetings, Uwe

Happy new year, if you aren't already there. Speaking of which, Taxi!


David.
 

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,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top