Can "self" crush itself?

N

n00m

Why does "h" instance stay alive?

class Moo:
cnt = 0
def __init__(self, x):
self.x = x
self.__class__.cnt += 1
if self.__class__.cnt > 2:
self.crush_me()
def crush_me(self):
print 'Will self be crushed?'
self = None

f = Moo(1)
g = Moo(2)
h = Moo(3)

print f
print g
print h


=============== RESTART ====

Will self be crushed?
<__main__.Moo instance at 0x00CC9260>
<__main__.Moo instance at 0x00CC9468>
<__main__.Moo instance at 0x00CC94B8>
 
N

n00m

Whatever you rebind ‘self’ to inside the function...


Seems you are right! Thanks, Ben, for the lesson :)


class Moo:
cnt = 0
def __init__(self, x):
self.x = x
self.__class__.cnt += 1
if self.__class__.cnt > 2:
self.crush_me()
def crush_me(self):
print 'Will self be crushed?'
self = None
print self

f = Moo(1)
g = Moo(2)
h = Moo(3)
print '================='
print h



Will self be crushed?
None
=================
<__main__.Moo instance at 0x00CC9468>
 
N

n00m

Then how can we destroy the 3rd instance,
right after its creation and from inside
class Moo code?

class Moo:
cnt = 0
def __init__(self, x):
self.x = x
self.__class__.cnt += 1
if self.__class__.cnt > 2:
print id(self)
## 13406816
## in what dict is this ID?
## and can we delete it from there?

## ???


f = Moo(1)
g = Moo(2)
h = Moo(3)
print h
 
C

Chris Rebert

Then how can we destroy the 3rd instance,
right after its creation and from inside
class Moo code?

Why would you want to do that in the first place? It's strange to say the least.
If you want to prevent an instance being created in the first place,
you can override __new__().

Cheers,
Chris
 
N

n00m

Why would you want to do that in the first place?

I don't know... :)
As Schoepenhauer put it:
The man can do what he wants to do but he can't want to want
what he wants to do
 
A

Aahz

If you want to prevent an instance being created in the first place,
you can override __new__().

Or just raise an exception in __init__(), which I think is more common
practice.
 
N

n00m

Or just raise an exception in __init__(),..

Then we are forced to handle this exception outside of class code.
It's Ok. Never mind.
--------------------

Next thing.
I can't understand why we can get __name__, but not __dict__,
on the module level?


print __name__
print __dict__

__main__

Traceback (most recent call last):
File "D:\Python25\zewrt.py", line 19, in <module>
print __dict__
NameError: name '__dict__' is not defined
 
T

Terry Reedy

n00m said:
Then we are forced to handle this exception outside of class code.
It's Ok. Never mind.
--------------------

Next thing.
I can't understand why we can get __name__, but not __dict__,
on the module level?


print __name__
print __dict__

If the global namespace contained itself, as a dict, there would be an
infinite loop.
 
S

Steven D'Aprano

If the global namespace contained itself, as a dict, there would be an
infinite loop.


Why would that be a problem? Any time you do this:


you create such a recursive reference:
globals()['g']['g']['g']['g'] is globals() is g
True


Yes, there's a tiny bit extra work needed when bootstrapping the
processes, and when exiting, but I don't see why it's a big deal. Whether
it's necessary or useful is another story.
 
N

n00m

aaah... globals()...
Then why "self" not in globals()?

class Moo:
cnt = 0
def __init__(self, x):
self.__class__.cnt += 1
if self.__class__.cnt < 3:
self.x = x
else:
print id(self)
for item in globals().items():
print item

f = Moo(1)
g = Moo(2)
h = Moo(3)

13407336
('g', <__main__.Moo instance at 0x00CC9260>)
('f', <__main__.Moo instance at 0x00CC9440>)
('__builtins__', <module '__builtin__' (built-in)>)
('Moo', <class __main__.Moo at 0x00CCC060>)
('__name__', '__main__')
('__doc__', None)
 
S

Steven D'Aprano

aaah... globals()...
Then why "self" not in globals()?

class Moo:
cnt = 0
def __init__(self, x):
self.__class__.cnt += 1


Because it isn't a global, it's a local -- it is defined inside a class.
Inside functions and classes, names you create are local, not global,
unless you declare them global.
 
M

Mel

n00m said:
aaah... globals()...
Then why "self" not in globals()?

class Moo:
cnt = 0
def __init__(self, x):
self.__class__.cnt += 1
if self.__class__.cnt < 3:
self.x = x
else:
print id(self)
for item in globals().items():
print item

f = Moo(1)
g = Moo(2)
h = Moo(3)

Because self is not in globals().

It's defined as a local symbol in Moo.__init__ , supplied to that function
as the first parameter.

Mel.
 
G

Gregory Ewing

n00m said:
I can't understand why we can get __name__, but not __dict__,
on the module level?

For much the same reason that you can see your own
feet but (unless you look in a mirror) you can't
see your own eyes.
 
N

n00m

Ok ok
Of course, it's a local name; -- just my silly slip.
And seems it belongs to no dict[]...
Just an internal volatile elf
 
L

Lie Ryan

n00m said:
Ok ok
Of course, it's a local name; -- just my silly slip.
And seems it belongs to no dict[]...
Just an internal volatile elf

Local names are not implemented as dict, but rather as sort of an array
in the compiler. The name resolution of locals is compile time and
doesn't use dictionary, that's why local is much faster than globals.
 
A

Aahz

Then we are forced to handle this exception outside of class code.

Absolutely! That's the whole point. If you can't construct the class,
you *should* raise an error. The only other workable option is to leave
the target set to None, which is uglier because you don't track the
error.
 

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

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,677
Members
48,796
Latest member
Greg L.

Latest Threads

Top