f********o 发帖数: 1163 | 1 #!/usr/bin/python
import os;
import sys;
class Person:
''' Defines a Person class '''
population = 0
def __init__(self,name):
''' I really hate the indents. '''
self.name = name;
print 'The person'"'s"'name is %s' % self.name;
Person.population += 1;
def __del__(self):
print '%s says bye;' % self.name
Person.population -= 1
if Person.population == 0:
print 'I am the last one, now I am gone'
else:
print 'There are still %d people left;' % Person.
population
def howMany(self):
if Person.population == 1:
print 'I am the last one, but I am still here' ;
else:
print 'We have %d people here.' % Person.population ;
Ao = Person('Ao Liu');
Ao.howMany();
John = Person('John Bay');
John.howMany();
Chris = Person('Chris Tunnel');
Chris.howMany();
运行后得到
The person'sname is Ao Liu
I am the last one, but I am still here
The person'sname is John Bay
We have 2 people here.
The person'sname is Chris Tunnel
We have 3 people here.
Ao Liu says bye;
There are still 2 people left;
Chris Tunnel says bye;
Exception AttributeError: "'NoneType' object has no attribute 'population'"
in
> ignored
John Bay says bye;
Exception AttributeError: "'NoneType' object has no attribute 'population'"
in
> ignored
后面的两个成员为什么没法访问Person.population了呢? 第一个成员离开的时候不只
是将其减一而已吗?
谢谢~ | p*****2 发帖数: 21240 | | f********o 发帖数: 1163 | 3
是有点。但你没有告诉我具体问题出在哪里。
【在 p*****2 的大作中提到】 : python class那个self很恶心。
| h*******s 发帖数: 8454 | 4 http://docs.python.org/2/reference/datamodel.html
It is not guaranteed that __del__() methods are called for objects that
still exist when the interpreter exits.
第二次的时候Person这个符号已经没了
【在 f********o 的大作中提到】 : #!/usr/bin/python : import os; : import sys; : class Person: : ''' Defines a Person class ''' : population = 0 : def __init__(self,name): : ''' I really hate the indents. ''' : self.name = name; : print 'The person'"'s"'name is %s' % self.name;
| m********5 发帖数: 17667 | 5 +1
【在 h*******s 的大作中提到】 : http://docs.python.org/2/reference/datamodel.html : It is not guaranteed that __del__() methods are called for objects that : still exist when the interpreter exits. : 第二次的时候Person这个符号已经没了
| m********5 发帖数: 17667 | 6 welcome to python world! I provided a fix which can run flawless to your
class design. Seems like u r from java ;) We should always Keep
in mind that, unlike java, python is a dynamic language.
The counterpart of static class variable of java is class variable.
Using the class name as a reference to a class is very common outside the
class def. However, it is not a very good idea to do so within the class def
, because any class itself is an instance of `type`. The name space looking-
up can mess up when u do so. I recommend @
classmethod to handle all "static class variable"
import os
import sys
class Person(object):
''' Defines a Person class '''
population = 0
def __init__(self,name):
''' I really hate the indents. '''
self.name = name
print 'The person'"'s"'name is %s' % self.name
self.__addpopulation__()
super(Person, self).__init__()
@classmethod
def __addpopulation__(cls):
cls.population+=1
def __del__(self):
print '%s says bye;' % self.name
self.__poppopulation__()
@classmethod
def __poppopulation__(cls):
cls.population -= 1
if cls.population == 0:
print 'I am the last one, now I am gone'
else:
print 'There are still %d people left;' % cls.population
@classmethod
def howMany(cls):
if cls.population == 1:
print 'I am the last one, but I am still here'
else:
print 'We have %d people here.' % cls.population
Ao = Person('Ao Liu')
Ao.howMany()
John = Person('John Bay')
John.howMany()
Chris = Person('Chris Tunnel')
Chris.howMany()
Chris = Person('David')
Chris.howMany()
$./delproblem2.py
The person'sname is Ao Liu
I am the last one, but I am still here
The person'sname is John Bay
We have 2 people here.
The person'sname is Chris Tunnel
We have 3 people here.
The person'sname is David
Chris Tunnel says bye;
There are still 3 people left;
We have 3 people here.
Ao Liu says bye;
There are still 2 people left;
David says bye;
There are still 1 people left;
John Bay says bye;
I am the last one, now I am gone
BTW: U'd better lose all the ";"
【在 f********o 的大作中提到】 : #!/usr/bin/python : import os; : import sys; : class Person: : ''' Defines a Person class ''' : population = 0 : def __init__(self,name): : ''' I really hate the indents. ''' : self.name = name; : print 'The person'"'s"'name is %s' % self.name;
| l********a 发帖数: 1154 | | f********o 发帖数: 1163 | 8 不应该啊,只是Person.population没有了,但还是say goodbye了啊?
【在 h*******s 的大作中提到】 : http://docs.python.org/2/reference/datamodel.html : It is not guaranteed that __del__() methods are called for objects that : still exist when the interpreter exits. : 第二次的时候Person这个符号已经没了
| f********o 发帖数: 1163 | 9 谢谢你的建议。但我还是没弄明白为什么我的不可以用。Person是一个class,怎么会
由于一个成员的退出就没有了呢?你看,第二个person还是say了goodbye。只是没有访
问到Person.population 而已。
【在 m********5 的大作中提到】 : +1
| m********5 发帖数: 17667 | 10 This is dynamic language. `Person` is NOT a C++ or java like `class`. `
Person` is just a name in global scope referring to an instance of `type`.
In another word `Person` is nothing but a key in the global name dictionary.
During interpretor exiting, as @hatemaths pointing out, when __del__ get
called, there is no guarantee any referred global name still exists (
deleting order is unpredictable). In this case `Person` in the global scope
has already being destroyed. But in the local scope it still exist. That is
why if u use the reference in local scope: `cls` in @classmethod, it will
still work.
Here I will show some detail with examples:
try to modify my class as following:
@classmethod
def __poppopulation__(cls):
print "gloals: ", globals()
print "locals: ", locals()
cls.population -= 1
if cls.population == 0:
print 'I am the last one, now I am gone'
else:
print 'There are still %d people left;' % cls.population
Then modify the instantiation part:
Ao = Person('Ao Liu');
Ao.howMany();
John = Person('John Bay');
John.howMany();
Chris = Person('Chris Tunnel');
Chris.howMany();
David = Person('David');
David.howMany();
print globals()
what u will see is like this:
#############################
The person'sname is Ao Liu
I am the last one, but I am still here
The person'sname is John Bay
We have 2 people here.
The person'sname is Chris Tunnel
We have 3 people here.
The person'sname is David
We have 4 people here.
#############################
#Here is the global dict:
globals(): {'__builtins__': , '__file_
_': './delproblem2b.py', 'Ao': <__main__.Person object at 0x7ff088126d10>, '
__package__': None, 'sys': , 'Person':
main__.Person'>, 'Chris': <__main__.Person object at 0x7ff088126d90>, '__
name__': '__main__', 'John': <__main__.Person object at 0x7ff088126d50>, 'os
': , '__doc__': None, 'David':
<__main__.Person object at 0x7ff088126dd0>}
#############################
# so after Ao get del, still 'Person':
###
Ao Liu says bye;
gloals: {'__builtins__': , 'Ao': None,
'__package__': None, 'sys': , 'Person':
main__.Person'>, 'Chris': <__main__.Person object at 0x7ff088126d90>, '__
name__': '__main__', 'John': <__main__.Person object at 0x7ff088126d50>, 'os
': , '__doc__': None, 'David':
<__main__.Person object at 0x7ff088126dd0>}
locals: {'cls': }
There are still 3 people left;
#############################
# But when Chris get del, 'Person': None
###
Chris Tunnel says bye;
gloals: {'__builtins__': , 'Ao': None,
'__package__': None, 'sys': None, 'Person': None, 'Chris': None, '__name__'
module 'os' from '/usr/lib/python2.7/os.pyc'>, '__doc__': None, 'David': <__
main__.Person object at 0x7ff088126dd0>}
locals: {'cls': }
There are still 2 people left;
#############################
# because 'Person' is refer to None, Person.population is actually,
#None.population. This is why u get an error in ur code.
###
John Bay says bye;
gloals: {'__builtins__': , 'Ao': None,
'__package__': None, 'sys': None, 'Person': None, 'Chris': None, '__name__'
'__doc__': None, 'David': <__main__.Person object at 0x7ff088126dd0>}
##But in the local scope of the instance of `Person class` is still ##exist.
locals: {'cls': }
There are still 1 people left;
David says bye;
gloals: {'__builtins__': , 'Ao': None,
'__package__': None, 'sys': None, 'Person': None, 'Chris': None, '__name__'
locals: {'cls': }
I am the last one, now I am gone
let's continue to play with the global name and demonstrate what the `
unpredictable` means. Create a new script with the *OP's* post as myscript1a.
py, with following modification:
add A to all the instances:
Ao = Person('Ao Liu');
Ao.howMany();
AJohn = Person('John Bay');
AJohn.howMany();
AChris = Person('Chris Tunnel');
AChris.howMany();
ADavid = Person('David');
ADavid.howMany();
###################
Chris Tunnel says bye;
There are still 3 people left;
David says bye;
There are still 2 people left;
Ao Liu says bye;
There are still 1 people left;
John Bay says bye;
Exception AttributeError: "'NoneType' object has no attribute '
population'" in
0x7f2f1f2e9ea8>> ignored
##we can see here the behavior changed!
So the behavior is not stable, it might related to the variable name, or to
other stuff, not for sure.
In certain cases, this will even create memory leak.
In general, as @libralibra said, we should avoid to use method __del__ with
global reference either explicitly or implicitly
I hope this will clear all the doubts u have. As I said, you should keep in
mind, Python is a dynamic language, which is nothing like the Java/C++, most
of the concepts you have learned in Java and C++ will surprise u in Python. | m********5 发帖数: 17667 | |
|