how to use 'pickle' - python

my code(i was unable to use 'pickle'):
class A(object):
def __getstate__(self):
print 'www'
return 'sss'
def __setstate__(self,d):
print 'aaaa'
import pickle
a = A()
s = pickle.dumps(a)
e = pickle.loads(s)
print s,e
print :
www
aaaa
ccopy_reg
_reconstructor
p0
(c__main__
A
p1
c__builtin__
object
p2
Ntp3
Rp4
S'sss'
p5
b. <__main__.A object at 0x00B08CF0>
who can tell me how to use.

What are you trying to do? It works for me:
class A(object):
def __init__(self):
self.val = 100
def __str__(self):
"""What a looks like if your print it"""
return 'A:'+str(self.val)
import pickle
a = A()
a_pickled = pickle.dumps(a)
a.val = 200
a2 = pickle.loads(a_pickled)
print 'the original a'
print a
print # newline
print 'a2 - a clone of a before we changed the value'
print a2
print
print 'Why are you trying to use __setstate__, not __init__?'
print
So this will print:
the original a
A:200
a2 - a clone of a before we changed the value
A:100
If you need setstate:
class B(object):
def __init__(self):
print 'Perhaps __init__ must not happen twice?'
print
self.val = 100
def __str__(self):
"""What a looks like if your print it"""
return 'B:'+str(self.val)
def __getstate__(self):
return self.val
def __setstate__(self,val):
self.val = val
b = B()
b_pickled = pickle.dumps(b)
b.val = 200
b2 = pickle.loads(b_pickled)
print 'the original b'
print b
print # newline
print 'b2 - b clone of b before we changed the value'
print b2
which prints:
Why are you trying to use __setstate__, not __init__?
Perhaps __init__ must not happen twice?
the original b
B:200
b2 - b clone of b before we changed the value
B:100

You are able to pickle (meaning, this code works as it should). You just seem to get a result, you don't expect. If you expect the same 'output', try:
import pickle
a = A()
s = pickle.dumps(a)
e = pickle.loads(s)
print s, pickle.dumps(e)
Your example isn't, well, a typical 'pickling' example. Usually pickled objects are saved somewhere persistently or sent over the wire. See e.g. pickletest.py: http://www.sthurlow.com/python/lesson10/.
There are advanced uses of pickling, see for example David Mertz XML object serialisation article: http://www.ibm.com/developerworks/xml/library/x-matters11.html

In a nutshell, in your example, e equals a.
Don't have to care about these strang strings, you can dumps these strings to save to anywhere, just remember when you loads them, you got 'a' object again.

Related

print object name, when object call a function inside the class

#!/usr/bin/env python
class AA(object):
def __init__(self):
pass
def y(self):
pass
x=AA()
x.y()
When I execute x.y(), I want to print "This is 'x' call me", how should I do it ?
I hope that this will solve your issue
#!/usr/bin/env python
class AA(object):
def __init__(self):
pass
def y(self, name):
self.name = name
print("This is %s call me" % name)
x = AA()
x.y("Tarzan")
Everything is an object in Python, When you create an instance of the class it allocate memory location and that memory location is referenced by your x variable.The only object has memory location, variable doesn't have any memory location. Variable just refer to objects memory location
in your example, X is nothing just reference to your memory location
if define a variable
a = 2
that means a reference to 2
a = 1
that means a now reference to 1
Assigning one variable to another makes a new tag bound to the same value as shown below.
b = a
that means a and b both reference to 1
id() in python return memory location
print id(a)
print id(b)
output
140621897573617
140621897573617
Example 1:
>>> s1 = 'hello'
>>> s2 = 'hello'
>>> id(s1), id(s2)
(4454725888, 4454725888)
>>> s1 == s2 True
>>> s1 is s2 True
>>> s3 = 'hello, world!'
>>> s4 = 'hello, world!'
>>> id(s3), id(s4) (4454721608, 4454721664)
>>> s3 == s4 True
>>> s3 is s4 False
Example 2
>>> class Foo:
... pass
...
>>> bar = Foo()
>>> baz = Foo()
>>> id(bar)
140730612513248
>>> id(baz)
140730612513320
result
Name of object or instance is nothing just reference to memory
location
From #user1334609 's comment:
for example, we have lots of vm instance,vm1=AA(),
vm1.run_cmd("xxxx"), vm2=AA(), vm2.run_cmd("") I want to know which vm
are run some cmd
To know which VM has run the command you can just use the id(self), instead of trying to find the declared variable in code.
Two options you have now to see from which vm, command is running.
Option1: Add a member variable to class. This can give readability.
Option2: Use the id of self in y(). This avoids adding additional variable.
Example code:
#!/usr/bin/env python
class AA(object):
def __init__(self, vmname):
self.whoami = vmname
def y(self):
print "My Name is %s " % self.whoami # Option1
print "My Id is %s " % id(self) # Option2
def main():
vm1=AA("Yoda")
vm1.y()
vm2=AA("Boda")
vm2.y()
vm3=AA("Anakin")
vm3.y()
if __name__ == '__main__':
main()
This gives following output:
My Name is Yoda
My Id is 139725977256656
My Name is Boda
My Id is 139725977256720
My Name is Anakin
My Id is 139725977256784
I have posted a complete solution here:
https://stackoverflow.com/a/49331683/7386061
It works without parameters. For example you could just do:
class AA(RememberInstanceCreationInfo):
def y(self):
print("my name is '"+self.creation_name+"'")
x=AA()
x.y()
out: my name is 'x'

Confusion in order of Destructor call in Python

I was going through this website http://eli.thegreenplace.net/2009/06/12/safely-using-destructors-in-python, I wrote the exactly similar code.
But in my code, the destructor is getting called once the object goes out of scope. But the code mentioned in the link above, the destructor gets called after the end of the code. How?
Here are codes;
Code from the link
class FooType(object):
def __init__(self, id):
self.id = id
print self.id, 'born'
def __del__(self):
print self.id, 'died'
def make_foo():
print 'Making...'
ft = FooType(1)
print 'Returning...'
return ft
print 'Calling...'
ft = make_foo()
print 'End...'
Output is :
Calling...
Making...
1 born
Returning...
End...
1 died <----- Destructor called
My Code:
abc = [1,2,3]
class myclass(object):
def __init__(self):
print "const"
abc = [7,8,9]
a = 4
def __del__(self):
print "Dest"
def hello():
abc = [4,5]
print abc
my = myclass()
print my.abc, my.a
print "I am before Dest"
return "Done"
ret = hello()
print ret
print abc
output:
[4, 5]
const
[7, 8, 9] 4
I am before Dest
Dest<---------- Destructor
Done
[1, 2, 3]
Because the object is returned by the function it is still in scope in the main program. In your example the object never leaves the function, so it goes out of scope when the function returns.

output is not printing string in python

i have made a program but the output that i'm getting is
(<q3v3.Student instance at 0x023BB620>, 'is doing the following modules:', ' <q3v3.Module instance at 0x023BB670> <q3v3.Module instance at 0x023BB698>')
For example , the above output should give me Alice is doing following module : biology, chemistry
Help
this is my full code:
class Student :
def __init__(self,students):
self.students= students
print self.students
#def __str__(self): # when i used this i've got error type TypeError: __str__ returned non-string (type NoneType)
#print str(self.students)
class Module:
def __init__(self,modules):
self.modules = modules
print self.modules
#def __str__(self):
#print str(self.modules)
class Registrations (Student,Module):
def __init__(self):
self.list= []
self.stulist = []
self.modulist= []
def __iter__(self):
return iter(self.list)
def __str__(self):
return str(self.list)
def add(self,students,modules):
self.list.append((students,modules))
#print (self.list)
def students(self,modules):
for i in self.list:
if i[1] == modules:
self.modulist.append((i[0]))
return iter(self.modulist)
def __str__(self):
return str(self.students)
def modules(self,students):
for i in self.list:
if i[0] == students:
self.stulist.append((i[1]))
return iter(self.stulist)
def __str__(self):
return str(self.modules)
i need to import my program to be able to run it to this :
from q3v4 import *
james = Student('james')
alice = Student('alice')
mary = Student('mary')
agm = Module('agm')
ipp = Module('ipp')
r = Registrations()
r.add(james,agm)
r.add(alice,agm)
r.add(alice,ipp)
mstr = ''
for m in map(str,r.modules(alice)):
mstr = mstr+' '+m
print(alice, 'is doing the following modules:', mstr)
sstr = ''
for s in map(str,r.students(agm)):
sstr = sstr+' '+s
print(agm, 'has the following students:', sstr)
print(r)
You could define a __str__ method in your Student class, and do something like this:
def __str__(self):
return self.name # Here the string you want to print
Are you using Python 2? If so, print is a keyword, not a function. There are two ways to solve your problem:
Write print foo, bar instead of print(foo, bar).
The difference is that print(foo, bar) is actually printing out the tuple (foo, bar), which uses the repr() representation of each element, rather than its str().
At the very top of your file, write from __future__ import print_function. This will magically convert print from a keyword into a function, causing your code to work as expected.
If you are using Python 3, my answer is irrelevant.

Creating new object in python is not returning a new object

I am new to python.
Why am I not getting a new object when I call tempMyObject = myObject()?
class myObject(object):
x = []
def getMyObject():
tempMyObject = myObject()
print "debug: %s"%str(tempMyObject.x)
tempMyObject.x.append("a")
return tempMyObject
#run
a = getMyObject()
b = getMyObject()
My debug prints out:
debug: []
debug: ["a"]
I don't understand why both of these debug arrays are not null, can someone please enlighten me?
EDIT: I found the mistake i put in python code on my post. I am using the .append("a") in my function
You have created x as a class variable rather than an instance variable. To associate the variable with a particular instance of a class, do something like this:
class myObject(object):
def __init__(self): # The "constructor"
self.x = [] # Assign x to this particular instance of myObject
>>> debug: []
>>> debug: []
For a little better explanation of what's going on, have a look at this little mockup that demonstrates the same thing, a little more explicitly (if also more verbosely).
class A(object):
class_var = [] # make a list attached to the A *class*
def __init__(self):
self.instance_var = [] # make a list attached to any *instance* of A
print 'class var:', A.class_var # prints []
# print 'instance var:', A.instance_var # This would raise an AttributeError!
print
a = A() # Make an instance of the A class
print 'class var:', a.class_var # prints []
print 'instance var:', a.instance_var # prints []
print
# Now let's modify both variables
a.class_var.append(1)
a.instance_var.append(1)
print 'appended 1 to each list'
print 'class var:', a.class_var # prints [1]
print 'instance var:', a.instance_var # prints [1]
print
# So far so good. Let's make a new object...
b = A()
print 'made new object'
print 'class var:', b.class_var # prints [1], because this is the list bound to the class itself
print 'instance var:', b.instance_var # prints [], because this is the new list bound to the new object, b
print
b.class_var.append(1)
b.instance_var.append(1)
print 'class var:', b.class_var # prints [1, 1]
print 'instance var:', b.instance_var # prints [1]
There a few bits missing in your code, like the class initialiser first and foremost. The correct code is as follows:
class myObject(object):
def __init__(self):
self.x=[] #Set x as an attribute of this object.
def getMyObject():
tempMyObject = myObject()
print "debug: %s"%str(tempMyObject.x) #Just after object initialisation this is an empty list.
tempMyObject.x = ["a"]
print "debug2: %s"%str(tempMyObject.x) #Now we set a value to it.
return tempMyObject
#run
a = getMyObject()
b = getMyObject()
Now the debug will first print out an empty list and then, once it was set, "a". Hope this helps. I recommend looking at basic python classes tutorial.

Does python allow calling of an instance variable name from an instance method?

I want to know if there is a way in python to call the name of an instance variable? For example, if I define a class
>>>class A(object):
... def get_instance_name(self):
... return # The name of the instance variable
>>>obj = A()
>>>obj.get_instance_name()
obj
>>>blah = A()
>>>blah.get_instance_name()
blah
Raise an exception. Not only is it the appropriate way to signal an error, it's also more useful for debugging. The traceback includes the line which did the method call but also additional lines, line numbers, function names, etc. which are more useful for debugging than just a variable name. Example:
class A:
def do(self, x):
if x < 0:
raise ValueError("Negative x")
def wrong(a, x):
a.do(-x)
wrong(A(), 1)
This gives a traceback similar to this, if the exception isn't caught:
Traceback (most recent call last):
File "...", line 1, in <module>
wrong(A(), 1)
File "...", line 7, in wrong
a.do(-x)
File "...", line 4, in do
raise ValueError("Negative x")
ValueError: Negative x
You can also use the traceback module to get this information programmatically, even without an exception (print_stack and friends).
globals() return a dictionary that represents the namespace of the module (the namespace is not this dictionary, this latter only represents it)
class A(object):
def get_instance_name(self):
for name,ob in globals().iteritems():
if ob is self:
return name
obj = A()
print obj.get_instance_name()
blah = A()
print blah.get_instance_name()
tu = (obj,blah)
print [x.get_instance_name() for x in tu]
result
obj
blah
['obj', 'blah']
.
EDIT
Taking account of the remarks, I wrote this new code:
class A(object):
def rondo(self,nameinst,namespace,li,s,seen):
for namea,a in namespace.iteritems():
if a is self:
li.append(nameinst+s+namea)
if namea=='__builtins__':
#this condition prevents the execution to go
# in the following section elif, so that self
# isn't searched among the cascading attributes
# of the builtin objects and the attributes.
# This is to avoid to explore all the big tree
# of builtin objects and their cascading attributes.
# It supposes that every builtin object has not
# received the instance, of which the names are
# searched, as a new attribute. This makes sense.
for bn,b in __builtins__.__dict__.iteritems():
if b is self:
li.append(nameinst+'-'+b)
elif hasattr(a,'__dict__') \
and not any(n+s+namea in seen for n in seen)\
and not any(n+s+namea in li for n in li):
seen.append(nameinst+s+namea)
self.rondo(nameinst+s+namea,a.__dict__,li,'.')
else:
seen.append(nameinst+s+namea)
def get_instance_name(self):
li = []
seen = []
self.rondo('',globals(),li,'')
return li if li else None
With the following
bumbum = A()
blah = A()
print "bumbum's names:\n",bumbum.get_instance_name()
print "\nmap(lambda y:y.get_instance_name(), (bumbum,blah) :\n",map(lambda y:y.get_instance_name(), (bumbum,blah))
print "\n[y.get_instance_name() for y in (bumbum,blah)] :\n",[y.get_instance_name() for y in (bumbum,blah)]
the result is
bumbum's names:
['bumbum']
map(lambda y:y.get_instance_name(), (bumbum,blah) :
[['bumbum'], ['blah']]
[y.get_instance_name() for y in (bumbum,blah)] :
[['bumbum', 'y'], ['blah', 'y']]
The second list comprehension shows that the function get_instance_name() must be used with care. In the list comp, identifier y is assigned in turn to every element of (bumbum,blah) then the finction finds it out as a name of the instance !
.
Now, a more complex situation:
ahah = A() # ahah : first name for this instance
class B(object):
pass
bobo = B()
bobo.x = ahah # bobo.x : second name for ahah
jupiter = bobo.x # jupiter : third name for ahah
class C(object):
def __init__(self):
self.azerty = jupiter # fourth name for ahah
ccc = C()
kkk = ccc.azerty # kkk : fifth name for ahah
bobo.x.inxnum = 1005
bobo.x.inxwhat = kkk # bobo.x.inxwhat : fifth name for ahah
# Since bobo.x is instance ahah, this instruction also
# creates attribute inxwhat in ahah instance's __dict__ .
# Consequently, instance ahah having already 5 names,
# this instruction adds 5 additional names, each one
# ending with .inxwhat
# By the way, this kkk being ahah itself, it results that ahah
# is the value of its own attribute inxwhat.
print ahah.get_instance_name()
result
['bobo.x', 'bobo.x.inxwhat',
'ahah', 'ahah.inxwhat',
'jupiter', 'jupiter.inxwhat',
'kkk', 'kkk.inxwhat',
'ccc.azerty', 'ccc.azerty.inxwhat']
I concur to judge this solution a little heavy and that if a coder thinks he needs such a heavy function, it is probably because the algorithm isn't optimal. But I find interesting to see that it's possible to do this in Python though it doesn't seem evident.
I say heavy, not hacky, I don't find it's hacky, by the way.
No, you can't. Objects can have any number of names, so the question doesn't even make sense. Consider:
a1 = a2 = a3 = A()
What is the name of the instance of A()?

Categories