由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - 请帮我看一下这个很简单的python问题在哪里。
相关主题
python还是有些傻傻的行为的Python macro question
准备学Java了,请推荐那本书开始面试被问了议题: check if an integer is power of 2
a question on python请教一个Android的简单HTTP REST编程问题 (转载)
一个关于 Python-dpkt 的问题有一个文件夹里有大概1000个文件。我有以下的Python语句调用后(转载)
Any possibility to make this expression faster?python download pdf
solidot上看来的some interview questions
问一个python的string split问题Does this function have memory problem?
which str_cmp code is better?CUDA问题请教。
相关话题的讨论汇总
话题: person话题: __话题: chris话题: ao话题: none
进入Programming版参与讨论
1 (共1页)
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
2
python class那个self很恶心。
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
7
不是说一般不建议自己写__del__()吗?
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
11
操, 楼主居然就这么消失了...
1 (共1页)
进入Programming版参与讨论
相关主题
CUDA问题请教。Any possibility to make this expression faster?
how to get client locale inside the running application?solidot上看来的
请教个throughput的问题问一个python的string split问题
C++里用Blas/Lapack的问题 (转载)which str_cmp code is better?
python还是有些傻傻的行为的Python macro question
准备学Java了,请推荐那本书开始面试被问了议题: check if an integer is power of 2
a question on python请教一个Android的简单HTTP REST编程问题 (转载)
一个关于 Python-dpkt 的问题有一个文件夹里有大概1000个文件。我有以下的Python语句调用后(转载)
相关话题的讨论汇总
话题: person话题: __话题: chris话题: ao话题: none