Re: Question about object lifetime and access
First of all many thanks to all for their detailed answers on subject. I really appreciate it! > Correct. The global name is a reference, so the reference count will be > > at least 1. In fact, referencing the name from a function or method > doesn't increase the ref count: > -- > > Steven i have tried some tests, though accessing object from functions increase refcount but only temporary and only if object is used within function. i guess as soon as k is bound to string object latter's reference count will increase and function return results in unbound of k from object (according to output below). What is interesting if module namespace can be held accountable for 1 reference count what are remaining 3 references counted on string object referenced by 'p'? (CPython 3.3.2, windows 7, run from within eclipse/PyDev and same output on centos 6.5 for python v3.3.3) from sys import getrefcount p = "test script" print("refcnt before func() ", getrefcount(p)) def access_p1(): global p print("refcnt inside func1()", getrefcount(p)) def access_p2(): global p k = p print("refcnt inside func2()", getrefcount(p)) access_p1() access_p2() print("refcnt after func() ", getrefcount(p)) -- Output: refcnt before func() 4 refcnt inside func1() 4 refcnt inside func2() 5 refcnt after func() 4 -- https://mail.python.org/mailman/listinfo/python-list
Re: Question about object lifetime and access
On Wed, 15 Jan 2014 05:14:59 -0800, Asaf Las wrote: > I have read somewhere that global objects are referenced from module > namespace will never have reference count down to 0 even if they are not > referenced from functions or class methods. Is this true? Correct. The global name is a reference, so the reference count will be at least 1. In fact, referencing the name from a function or method doesn't increase the ref count: instance = 123.456789 # ref count of float is 1 def test(): print(instance) # This refers to the *name* "instance", not the float So the test() function cannot keep the float alive. If you reassign global instance, test() will see the new value, not the old, and 123.456789 is free to be garbage collected. This sounds more complicated than it actually is. In practice it works exactly as you expect global variables to work: py> test() 123.456789 py> instance = 98765.4321 py> test() 98765.4321 > Does it mean > that global objects are destroyed when interpreter exits or thread where > it runs is terminated? Certainly not! Global objects are no different from any other object. They are destroyed when their reference count falls to zero. In the case of global objects, that is *often* not until the interpreter exits, but it can be before hand. So long as the object is in use, it will be kept. When it is no longer in use, the garbage collector is free to destroy it. So long as *some* object or name holds a reference to it, it is considered to be in use. value = instance = 1.23456 # ref count 2 alist = [1, 2, 3, 4, 5, value] # ref count now 3 mydict = {"Key": alist} # ref count now 4 value = 42 # rebind a name, ref count of float now 3 mydict.clear() # ref count now 2 del instance# delete the name, ref count now 1 assert alist[5] == 1.23456 alist[5] = 0# final reference gone, ref count is now 0 At this point the global object 1.23456 is free to be destroyed. (Note: some Python implementations don't do reference counting, e.g. Jython and IronPython use the Java and .Net garbage collectors respectively. In their case, the same rule applies: where there are no longer any references to an object, it will be garbage collected. The only difference is in how soon that occurs: in CPython, it will be immediate, in Jython or IronPython it will occur when the garbage collector runs.) -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: Question about object lifetime and access
Thanks! On Wednesday, January 15, 2014 3:05:43 PM UTC+2, Chris Angelico wrote: > > > > Questions are: > > > - what is the lifetime for global object (p in this example). > > > - will the p always have value it got during module loading > > > - if new thread will be created will p be accessible to it > > > - if p is accessible to new thread will new thread initialize p value again? > > > - is it guaranteed to have valid p content (set to "module is loaded") > > whenever application() function is called. > > > - under what condition p is cleaned by gc. > > > > Your global p is actually exactly the same as the things you imported. > > In both cases, you have a module-level name bound to some object. So > > long as that name references that object, the object won't be garbage > > collected, and from anywhere in the module, you can reference that > > name and you'll get that object. (Unless you have a local that shadows > > it. I'll assume you're not doing that.) > > > > How do you go about creating threads? Is it after initializing the > > module? If so, they'll share the same p and the same object that it's > > pointing to - nothing will be reinitialized. > > > > As long as you don't change what's in p, it'll have the same value > > ([1] - handwave) whenever application() is called. That's a guarantee. > > > > For your lambda functions, you could simply make them module-level > > functions. You could then give them useful names, too. But decide > > based on code readability rather than questions of performance. At > > this stage, you have no idea what's going to be fast or slow - wait > > till you have a program that's not fast enough, and then *profile it* > > to find the slow bits. Unless you're doing that, you're completely > > wasting your time trying to make something faster. Start with > > readable, idiomatic code, code that you could come back to in six > > months and be confident of understanding. Do whatever it takes to > > ensure that, and let performance take care of itself. Nine times out > > of ten, you won't even have a problem. In the past twelve months, I > > can think of exactly *one* time when I needed to improve an app's > > performance after I'd coded it the readable way, and there was just > > one part of the code that needed to be tweaked. (And it was more of an > > algorithmic change than anything else, so it didn't much hurt > > readability.) Remember the two rules of code optimization: > > > > 1. Don't. > > 2. (For experts only) Don't yet. > > > > Follow those and you'll save more time than you would gain by > > micro-optimizing. And your time is worth more than the computer's. > > > > ChrisA > > > > [1] Technically p doesn't "have a value" at all. It's a name that's > > bound to some object. You can rebind it to another object, you can > > mutate the object it's bound to (except that you've bound it to a > > string, which is immutable), or you can sever the connection (with > > 'del p'), but in simple terms, it's generally "near enough" to say > > that p has a value. -- https://mail.python.org/mailman/listinfo/python-list
Re: Question about object lifetime and access
Thanks a lot for detailed answer! i plan to assign object to name only when module loads, that means outside of function or class method. Then object will be accessed from functions only for read purpose. I have read somewhere that global objects are referenced from module namespace will never have reference count down to 0 even if they are not referenced from functions or class methods. Is this true? Does it mean that global objects are destroyed when interpreter exits or thread where it runs is terminated? On Wednesday, January 15, 2014 2:13:56 PM UTC+2, Asaf Las wrote: > Hi community > > > > i am beginner in Python and have possibly silly questions i could not figure > out answers for. > > > > Below is the test application working with uwsgi to test json-rpc. > > > > from multiprocessing import Process > > from werkzeug.wrappers import Request, Response > > from werkzeug.serving import run_simple > > > > from jsonrpc import JSONRPCResponseManager, dispatcher > > > > p = "module is loaded" <-- (3) > > print(p) > > print(id(p)) > > > > @Request.application > > def application(request): > > print("server started") > > > > print(id(p)) > > > > # Dispatcher is dictionary {: callable} > > dispatcher["echo"] = lambda s: s < (1) > > dispatcher["add"] = lambda a, b: a + b < (2) > > > > print("request data ==> ", request.data) > > response = JSONRPCResponseManager.handle(request.data, dispatcher) > > return Response(response.json, mimetype='application/json') > > > > > > As program will grow new rpc method dispatchers will be added so there is > idea to reduce initialization code at steps 1 and 2 by making them global > objects created at module loading, like string p at step 3. > > > > Multithreading will be enabled in uwsgi and 'p' will be used for read only. > > > > Questions are: > > - what is the lifetime for global object (p in this example). > > - will the p always have value it got during module loading > > - if new thread will be created will p be accessible to it > > - if p is accessible to new thread will new thread initialize p value again? > > - is it guaranteed to have valid p content (set to "module is loaded") > whenever application() function is called. > > - under what condition p is cleaned by gc. > > > > The rationale behind these question is to avoid object creation within > application() whose content is same and do not change between requests > calling application() function and thus to reduce script response time. > > > > Thanks in advance! -- https://mail.python.org/mailman/listinfo/python-list
Re: Question about object lifetime and access
On Wed, Jan 15, 2014 at 11:13 PM, Asaf Las wrote: > Questions are: > - what is the lifetime for global object (p in this example). > - will the p always have value it got during module loading > - if new thread will be created will p be accessible to it > - if p is accessible to new thread will new thread initialize p value again? > - is it guaranteed to have valid p content (set to "module is loaded") > whenever application() function is called. > - under what condition p is cleaned by gc. Your global p is actually exactly the same as the things you imported. In both cases, you have a module-level name bound to some object. So long as that name references that object, the object won't be garbage collected, and from anywhere in the module, you can reference that name and you'll get that object. (Unless you have a local that shadows it. I'll assume you're not doing that.) How do you go about creating threads? Is it after initializing the module? If so, they'll share the same p and the same object that it's pointing to - nothing will be reinitialized. As long as you don't change what's in p, it'll have the same value ([1] - handwave) whenever application() is called. That's a guarantee. For your lambda functions, you could simply make them module-level functions. You could then give them useful names, too. But decide based on code readability rather than questions of performance. At this stage, you have no idea what's going to be fast or slow - wait till you have a program that's not fast enough, and then *profile it* to find the slow bits. Unless you're doing that, you're completely wasting your time trying to make something faster. Start with readable, idiomatic code, code that you could come back to in six months and be confident of understanding. Do whatever it takes to ensure that, and let performance take care of itself. Nine times out of ten, you won't even have a problem. In the past twelve months, I can think of exactly *one* time when I needed to improve an app's performance after I'd coded it the readable way, and there was just one part of the code that needed to be tweaked. (And it was more of an algorithmic change than anything else, so it didn't much hurt readability.) Remember the two rules of code optimization: 1. Don't. 2. (For experts only) Don't yet. Follow those and you'll save more time than you would gain by micro-optimizing. And your time is worth more than the computer's. ChrisA [1] Technically p doesn't "have a value" at all. It's a name that's bound to some object. You can rebind it to another object, you can mutate the object it's bound to (except that you've bound it to a string, which is immutable), or you can sever the connection (with 'del p'), but in simple terms, it's generally "near enough" to say that p has a value. -- https://mail.python.org/mailman/listinfo/python-list
Re: Question about object lifetime and access
On 1/15/14 7:13 AM, Asaf Las wrote: Hi community i am beginner in Python and have possibly silly questions i could not figure out answers for. Below is the test application working with uwsgi to test json-rpc. from multiprocessing import Process from werkzeug.wrappers import Request, Response from werkzeug.serving import run_simple from jsonrpc import JSONRPCResponseManager, dispatcher p = "module is loaded" <-- (3) print(p) print(id(p)) @Request.application def application(request): print("server started") print(id(p)) # Dispatcher is dictionary {: callable} dispatcher["echo"] = lambda s: s < (1) dispatcher["add"] = lambda a, b: a + b < (2) print("request data ==> ", request.data) response = JSONRPCResponseManager.handle(request.data, dispatcher) return Response(response.json, mimetype='application/json') As program will grow new rpc method dispatchers will be added so there is idea to reduce initialization code at steps 1 and 2 by making them global objects created at module loading, like string p at step 3. Multithreading will be enabled in uwsgi and 'p' will be used for read only. The important concepts to understand are names and values. All values in Python work the same way: they live until no name refers to them. Also, any name can be assigned to (rebound) after it has been defined. This covers the details in more depth: http://nedbatchelder.com/text/names.html Questions are: - what is the lifetime for global object (p in this example). The name p is visible in this module for as long as the program is running. The object you've assigned to p can be shorter-lived if p is reassigned. - will the p always have value it got during module loading Depends if you reassign it. - if new thread will be created will p be accessible to it If the thread is running code defined in this module, yes, that code will be able to access p in that thread. - if p is accessible to new thread will new thread initialize p value again? No, the module is only imported once, so the statements at the top level of the module are only executed once. - is it guaranteed to have valid p content (set to "module is loaded") whenever application() function is called. Yes, unless you reassign p. - under what condition p is cleaned by gc. Names are not reclaimed by the garbage collector, values are. The value assigned to p can be reclaimed if you reassign the name p, and nothing else is referring to the value. The rationale behind these question is to avoid object creation within application() whose content is same and do not change between requests calling application() function and thus to reduce script response time. Thanks in advance! Welcome. -- Ned Batchelder, http://nedbatchelder.com -- https://mail.python.org/mailman/listinfo/python-list