Python garbage collector [closed] - python

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Given the code sample below, what is the life cycle for bb in in example 1 and for self.bb in example 2
Example 1
import B
class A:
def __init__( self ):
bb = B( self )
Example 2
import B
class A:
def __init__( self ):
self.bb = B( self )
Edit:
B is another class and for some reason i found it was not garbage collected in the first example. I looked more carefully in my code and i found out B class created a new class C and gave a ref to one of its methods to that C class. In the end C instantiated a loop back thread to wait for events hence B class instance was still alive even though A class init was done.
Thanks all for your answers.

On both cases there will be no reference to the B instance until you instantiate A.
Once you instantiate A, in the first case it will be discarded right after __init__ runs because bb will be out of scope and there will be no reference left to that B instance, so it will be garbage-collected on the next GC cycle (exactly when is an implementation detail). On the second case, the reference to that B instance will exist as long as a reference for the A instance exists or until you manually remove it.

In first example bb is local variable for function __init__ The bb variable can access within the same __init__ function.
In 2nd example self.bb is Instance variables for every class object.

They has not any life-time. You have to inherited.
Example 1
import B
class A:
def __init__( self ):
B.__init__(self)
bb = B()
Example 2
import B
class A:
def __init__( self ):
B.__init__(self)
bb = B()
For more information about init

Related

Sum of items of a class [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed yesterday.
Improve this question
What I have to do is to create a class that counts from a giving single argument and itself make the arithmetical operation.
class Counts:
def __init__(self, value=0):
self.value = value
def newvalue(self, other):
return Counts(self.value + other)
But for every I make to the code I got any different error, either syntax or callable argument.
The idea is to get
Counts()
Expected output
0
Next
Counts.newvalue(10)
Expected output
10
Next
Counts.newvalue(40)
Expected output
50
Next
Counts.newvalue(-17)
Expected output
33
And so on.
The code that shows the expected behaviour is
class Counts:
value = 0
def __new__(self):
return self.value
#classmethod
def newvalue(cls, other):
cls.value += other
return cls.value
however this is a somewhat strange piece of code, as you are creating a class that returns a value when initialized instead of an object deriving from that class by overriding __new__, which is pretty non-standard.
also if you want to zero the value whenever Count() is called, you can add a self.value = 0 before the return self.value
Tests ->
print(Counts())
print(Counts.newvalue(10))
print(Counts.newvalue(40))
print(Counts.newvalue(-17))
returns
0
10
50
33

Value Changed in Class B calls function in Class A to update object of class A

I want to call a function from a class A inside another class B. However, it should be called for an object of A. I mean if I have something like this:
class A:
def __init__(self, ....):
self.valuechanged=False
# do something
objectfromb=B()
self.somearray.append(objectfromb)
def updateevent(self):
self.valuechanged=True
# do some things if update event triggered
class B:
def __init__(self,...):
self.somevalue=0
self.someothervalue=1
# do something
def updatesomevalue(self,somenewvalue):
self.somevalue=somenewvalue
# !!! HERE SHOULD BE A CALL TO CLASS A FUNCTION updateevent
And in my code I use the classes like this:
a=A()
Then i would have a list somearray in a (a.somearray) which contains an object of B. So if I want to update this object B with:
a.somearray[0].updatesomevalue(10)
Then there should not only be a new value for a.somearray[0].somevalue but also the function update event of class A should trigger changing a. How can I do that?
There are two ways I can think of to achieve this without invoking any special magic.
The first is to have objects of type B know what object A they belong to so that they can call updateevent on it. This isn't a way I'm generally a fan of as there's extra admin work to do when moving instances of B between instances of A and such. If that's not a concern then it may be the best way. You'd do that something like this (with a method on A to create a B and set the correct parent for convenience):
class A:
valuechanged=False
somearray=[]
def add_b(self):
b = B(self)
somearray.append(b)
return b
def updateevent(self):
self.valuechanged=True
class B:
somevalue=0
someothervalue=1
def __init__(self, parent):
self.parent = parent
def updatesomevalue(self,somenewvalue):
self.somevalue=somenewvalue
self.parent.updateevent()
The second is to provide a method on A that does both tasks. This is only suitable if 1) you know A will always contains instances of B and only B and 2) B's interface is relatively small (to avoid providing lots of methods of this type on A). You would implement this as something like:
class A:
valuechanged=False
somearray=[]
def updatesomevalue(self, index, new_value):
somearray[index].updatesomevalue(new_value)
self.updateevent()
def updateevent(self):
self.valuechanged=True
class B:
somevalue=0
someothervalue=1
def updatesomevalue(self,somenewvalue):
self.somevalue=somenewvalue
Something I haven't addressed is that somearray, somevalue, etc are all being created as class attributes in your example (i.e. they will be shared among all instances, instead of each instance having its own ones). This is likely not what you wanted.

Inside class access to outside class variable? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have classes: C1 and C2, a C1 instance is created inside C2, and some C1 class functions also need variables from C2. Although I can move those function inside C2, it would be a little bit messy. Is there any way to import C2's variable into the test_func in C1?
C1_class.py:
class C1():
C1_a = 1
C1_b = 2
def test_func(self):
result = self.C1_a*C2.C2_a+self.C1_b*C2.C2_b
return result
C2_class.py
import C1
class C2():
C2_a = 1
C2_b = 2
C1_sample = C1_class.C1()
C2_sample = C2()
print(C2_sample.C1_sample.test_func)
Printing the function isn't what you want, I think ... you want the functional value, correct?
print(C2_sample.C1_sample.test_func() )
# ^^ forgot the parentheses
Output:
5
The problem is not that they're in two different files. It's that you haven't called the function.
test_func
is the function descriptor, giving you access to that object.
It's attributes include the parameters, etc.
test_func()
is a call to the function, returning a value.

Designing a black box python [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I want to have a black box in python where
The input is a list A.
There is a random number C for the black box which is randomly selected the first time the black box is called and stays the same for the next times the black box is called.
Based on list A and number C, the output is a list B.
I was thinking of defining this black box as a function but the issue is that a function cannot keep the selected number C for next calls. Note that the input and output of the black box are as described above and we cannot have C also as output and use it for next calls. Any suggestion?
Make it a Class so C will persist.
class BlackBox():
def __init__(self):
self.C = rand.randint(100)
etc...
As a side note, using some pretty cool Python functionality...
You can make objects of this class callable by implementing __call__() for your new class.
#inside the BlackBox class
def __call__(self, A):
B = []
#do something to B with A and self.C
return B
You can then use this in your main code.
bb = BlackBox()
A = [1, 2, 3]
B = bb(A)
the issue is that a function cannot keep the selected number C for next calls.
This may be true in other languages, but not so in Python. Functions in Python are objects like any other, so you can store things on them. Here's a minimal example of doing so.
import random
def this_function_stores_a_value():
me = this_function_stores_a_value
if 'value' not in me.__dict__:
me.value = random.random()
return me.value
This doesn't directly solve your list problem, but it should point you in the right direction.
Side note: You can also store persistent data in optional arguments, like
def this_function_also_stores_a_value(value = random.random()):
...
I don't, however, recommend this approach because users can tamper with your values by passing an argument explicitly.
There are many ways to store persistent data for a function. They all have their uses, but in general, the ones that come first are useful more often than the ones that come later. (To keep things shorter, I'm solving a slightly simpler problem than the one you asked about, but it should be obvious how to adapt it.)
Instance attribute
class BlackBox:
def __init__(self):
self.C = rand.randint(100)
def check(self, guess):
return (guess - self.C) / abs(guess - self.C)
Now you can create one or more BlackBox() instances, and each one has its own random number.
Closure variable
def blackbox():
C = rand.random()
def check(guess):
return (guess - C) / abs(guess - C)
return check
Now, you can create one or more check functions, and each one has its own random number. (This is dual to the instance variable—that is, it has the same capabilities—but usually one or the other is more readable.)
Global variable
def makeblackbox():
global C
C = random.randint(100)
def check(guess):
return (guess - C) / abs(guess - C)
This way, there's only a single blackbox for the entire program. That's usually not as good a design, which is one of the reasons that "globals are bad". Plus, it's polluting the global namespace with a C variable that means nothing to anyone but the check function, which is another one of the reasons that "globals are bad".
Function attribute
def makeblackbox():
check.C = random.randint(100)
def check():
return (guess - check.C) / abs(guess - check.C)
This is equivalent to a global in that you can only ever have one black box, but at least the variable is hidden away on the check function instead of polluting the global namespace.
Class attribute
class BlackBox:
C = rand.randint(100)
#staticmethod
def check(guess):
return (guess - BlackBox.C) / abs(guess - BlackBox.C)
This is again equivalent to a global variable without polluting the global namespace. But it has a downside over the function attribute—you're creating a class that has no useful instances is often misleading.
Class attribute 2
class BlackBox:
C = rand.randint(100)
#classmethod
def check(cls, guess):
return (guess - cls.C) / abs(guess - cls.C)
This is different from the last three in that you can create new blackboxes by creating subclasses of BlackBox. But this is very rarely what you actually want to do. If you want multiple persistent values, you probably want instances.
Since you are asking in the comments.
This is probably not recommended way but it's easy and works so I'll add it here.
You can use global variable to achieve your goal.
import random
persistant_var = 0
def your_func():
global persistant_var
if persistant_var:
print('variable already set {}'.format(persistant_var))
else:
print('setting variable')
persistant_var = random.randint(1,10)
your_func()
your_func()
Output:
setting variable
variable already set 7
Hope this is clear.

python: confusion with local class name

I have the following code:
def f():
class XYZ:
# ...
cls = type('XXX', (XYZ, ), {})
# ...
return cls
I am now using it as follows:
C1 = f()
C2 = f()
and it seems to work fine: C1 is C2 returns False, there's no conflict between the class attributes of the two classes, etc.
Question 1
Why is that? How is it possible that C1 and C2 are both shown as class
<'__main__.XXX'>
and yet not the same class?
Question 2
Is there some problem with the fact that I have two identical names for two different classes?
Question 3
I would like to be able to write instead:
f('C1')
f('C2')
with the same effect. Is it possible?
Question 4
If I want C1 to look like a regular class, not main.XXX, is it ok to say:
C1.__name__ = '__main__.C1'
Question 3
To have cls.__name__ be anything you want, (with a nod to delnan's suggestion)
def f(clsname):
class XYZ:
# ...
XYZ.__name__ = XYZ
# ...
return XYZ
Question 1
The reason that c1 is not c2 is that they are two different objects stored at two different locations in memory.
Question 4
Try an answer to question 1 and see how it works out for you
Question 2
It can complicate debugging that their class attributes __name__ share a common value and this is bad enough to take pains to avoid. (see question 3). I would maintain though that they don't have the same name. One is named C1 and the other is named C2 (at least in the scope you are showing. If you were to pass them to a function, then there name in that scope would be the same as the name of parameter that they were passed through)
In fact, I'm so sure that they don't have the same name that trying to tell me otherwise is likely to cause me to turn the music up louder and pretend I can't hear you.
In response to comment
It can be done but it's just wrong. I'll illustrate anyway because it's illuminating:
def f(clsname):
class XYZ(object):
pass
XYZ.__name__ = clsname
globals()[clsname] = XYZ
f('C1')
f('C2')
print C1
print C2
This just works by sticking the class in the globals dict keyed by clsname. But what's the point? You can stick it in the globals dict under any name in fact because this is just another assignment. You are best off just returning the class from the function and letting the caller decide what name to give the class in it's own scope. You still have the __name__ attribute of the class set to the string you pass to the function for debugging purposes.
Actually, you don't need to the cls = ... line at all.
>>> def f():
... class C:
... pass
... return C
...
>>> f() is f()
False
Reason: class (as well as e.g. def) defines a new class each time it is encountered = each time the function is called.
As for cls.__name__, it's really no semantic difference. The name is useful for debugging (you don't expose it directly to the user, do you?) and introspection, but it shouldn't be an issue. But if you absolutely want to have different names, you can change cls.__name__ before returning (also note that after C.__name__ = 'foo', C.__name__ == '__main__.foo'!).
At question 3: It would be possible to inject it directly into global namespace... don't do this. It has no advantages, only disatvantages: nonobvious side effects, bad style, the fact it's a hack at all, etc!

Categories

Resources