Here is my situation, what should I write in place of the comment?
Thank you in advance, and sorry if I asked something alredy answered.
I have alredy searched for an answer but without success.
#!/usr/bin/python3.4
class A(object):
def __init__(self):
print("A constructor")
class B(A):
def __init__(self):
super(B, self).__init__()
print("B constructor")
class C(A):
def __init__(self):
super(C, self).__init__()
print("C constructor")
class D(B,C):
def __init__(self):
""" what to put here in order to get printed:
B constructor
C constructor
A constructor
D constructor
or
C constructor
B constructor
A constructor
D constructor
?
(notice I would like to print once 'A constructor')
"""
print("D constructor")
if __name__ == "__main__":
d = D()
I found that changing a little the class constructors code does what I needed:
#!/usr/bin/python3.4
class A(object):
def __init__(self):
print("A constructor")
class B(A):
def __init__(self):
if self.__class__ == B:
A.__init__(self)
print("B constructor")
class C(A):
def __init__(self):
if self.__class__ == C:
A.__init__(self)
print("C constructor")
class D(B,C):
def __init__(self):
B.__init__(self) #
C.__init__(self) # if B constructor should be
A.__init__(self) # called before of C constructor
print("D constructor") #
# C.__init__(self) #
# B.__init__(self) # if C constructor should be
# A.__init__(self) # called before of B constructor
# print("D constructor") #
if __name__ == "__main__":
d = D()
Related
I want to share my embedding in Encoder and Decoder, I do it something like this:
from torch import nn
class FooDecoder(nn.Module):
def __init__(self, embedding):
super().__init__()
self.embedding = embedding
class FooEncoder(nn.Module):
def __init__(self, embedding):
super().__init__()
self.embedding = embedding
class Foo(nn.Module):
def __init__(self):
super().__init__()
self.embedding = nn.Embedding(10, 10)
self.encoder = FooEncoder(self.embedding)
self.decoder = FooDecoder(self.embedding)
model = Foo()
But I find that I will have two different params in state_dict:
state_dict = model.state_dict()
print(state_dict.keys()) # odict_keys(['embedding.weight', 'encoder.embedding.weight', 'decoder.embedding.weight'])
It seems PyTorch copy the embedding, I want to know:
embedding.weight encoder.embedding.weight decoder.embedding.weight will always keep the same in forward propagation and backward propagation?
Does this mean parameter increase if I do so?)(Because I have three embeeding weight)
Do I have any better way do this?
I can represent the my Simple_Dict_Subclass and List_Subclass with json.dumps, but not Custom_Dict_Subclass. When json.dumps is called on List_Subclass its __iter__ method is called, so I reasoned that json.dumps would call a dictionary's items method. And items is called in Simple_Dict_Subclass but not Custom_Dict_Subclass. How can I make my Custom_Dict_Subclass json serializable like Simple_Dict_Subclass?
import json
class Custom_Dict_Subclass(dict):
def __init__(self):
self.data = {}
def __setitem__(self, key, value):
self.data[key] = value
def __getitem__(self, key):
return self.data[key]
def __str__(self):
return str(self.data)
def items(self):
print("'Items' called from Custom_Dict_Subclass")
yield from self.data.items()
class Simple_Dict_Subclass(dict):
def __setitem__(self, key, value):
super().__setitem__(key, value)
def __getitem__(self, key):
return super().__getitem__(key)
def __str__(self):
return super().__str__()
def items(self):
print("'Items' called from Simple_Dict_Subclass")
yield from super().items()
class List_Subclass(list):
def __init__(self):
self.data = []
def __setitem__(self, index, value):
self.data[index] = value
def __getitem__(self, index):
return self.data[index]
def __str__(self):
return str(self.data)
def __iter__(self):
yield from self.data
def append(self, value):
self.data.append(value)
d = Custom_Dict_Subclass()
d[0] = None
print(d) # Works
print(json.dumps(d)) # Does't work
d = Simple_Dict_Subclass()
d[0] = None
print(d) # Works
print(json.dumps(d)) # Works
l = List_Subclass()
l.append(None)
print(l) # Works
print(json.dumps(l)) # Works
Output:
{0: None} # Custom dict string working
{} # Custom dict json.dumps not working
{0: None} # Simple dict string working
'Items' called from Simple_Dict_Subclass
{"0": null} # Simple dict json.dumps working
[None] # List string working
[null] # List json.dumps working
Generally speaking, it is not safe to assume that json.dumps will
trigger the items method of the dictionary. This is how it is
implemented but you cannot rely on that.
In your case, the Custom_Dict_Subclass.items is never called because
(key, value) pairs are not added to the dict object but to its
data attribute.
To fix that you need to invoke the super methods in
Custom_Dict_Subclass:
class Custom_Dict_Subclass(dict):
def __init__(self):
dict.__init__(self)
self.data = {}
def __setitem__(self, key, value):
self.data[key] = value
super().__setitem__(key, value)
The object is dumped correctly, but of course, (key, value) will then
be stored twice: in the dict object and in its data attribute.
In that situation, it is better to define a sub class of
json.JSONEncoder to implement the translation of a
Custom_Dict_Subclass object to a json serialisable object and to
give this class as the keyword argument cls of json.dumps:
import json
class Custom_Dict_Subclass:
def __init__(self):
self.data = {}
def __setitem__(self, key, value):
self.data[key] = value
def __getitem__(self, key):
return self.data[key]
def __str__(self):
return str(self.data)
def items(self):
print("'Items' called from Custom_Dict_Subclass")
yield from self.data.items()
class CustomDictEncoder(json.JSONEncoder):
def default(self, obj):
"""called by json.dumps to translate an object obj to
a json serialisable data"""
if isinstance(obj, Custom_Dict_Subclass):
return obj.data
return json.JSONEncoder.default(self, obj)
d = Custom_Dict_Subclass()
d[0] = None
print(json.dumps(d, cls=CustomDictEncoder))
I met a problem of pickle, Code is that:
import cPickle
class A(object):
def __init__(self):
self.a = 1
def methoda(self):
print(self.a)
class B(object):
def __init__(self):
self.b = 2
a = A()
self.b_a = a.methoda
def methodb(self):
print(self.b)
if __name__ == '__main__':
b = B()
with open('best_model1.pkl', 'w') as f:
cPickle.dump(b, f)
Error is that:
File "/usr/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
raise TypeError, "can't pickle %s objects" % base.name TypeError: can't pickle instancemethod objects
You can if you use dill instead of cPickle.
>>> import dill
>>>
>>> class A(object):
... def __init__(self):
... self.a = 1
... def methods(self):
... print(self.a)
...
>>>
>>> class B(object):
... def __init__(self):
... self.b = 2
... a = A()
... self.b_a = a.methods
... def methodb(self):
... print(self.b)
...
>>> b = B()
>>> b_ = dill.dumps(b)
>>> _b = dill.loads(b_)
>>> _b.methodb()
2
>>>
Also see:
Can't pickle <type 'instancemethod'> when using python's multiprocessing Pool.map()
Also, when dill is installed pickle will work but as usual not cPickle.
import cPickle, pickle
class A(object):
def __init__(self):
self.a = 1
def methoda(self):
print(self.a)
class B(object):
def __init__(self):
self.b = 2
a = A()
self.b_a = a.methoda
def methodb(self):
print(self.b)
# try using cPickle
try:
c = cPickle.dumps(b)
d = cPickle.loads(c)
except Exception as err:
print('Unable to use cPickle (%s)'%err)
else:
print('Using cPickle was successful')
print(b)
print(d)
# try using pickle
try:
c = pickle.dumps(b)
d = pickle.loads(c)
except Exception as err:
print('Unable to use pickle (%s)'%err)
else:
print('Using pickle was successful')
print(b)
print(d)
>>> Unable to use cPickle (can't pickle instancemethod objects)
>>> Using pickle was successful
>>> <__main__.B object at 0x10e9b84d0>
>>> <__main__.B object at 0x13df07190>
for whatever reason, cPickle is not simply a C version of pickle 100 times faster but there are some differences
I have a little problem with a variable update.
I have my variable declared in my first function as such self.TestVar = 0
then if a certain count ==2 self.TestVar = 2
in a second function (in the same class) but called from within another class I want returning self.TestVar. no way.
AttributeError: 'ThndClass' object has no attribute 'TestVar'
I am most certainly not doing the good way, all I want is accessing self.TestVar = 2 from my other class that's it's but I can't find a proper way to do so in Python.
It looks like my issue is that I get my self.TestVar = 2 in a "if" statement which make it live in another scope (or I might be wrong).
import sys
from PIL import Image
from PyQt4 import QtCore, QtGui
class MainWindow(QtGui.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.initUI()
def initUI(self):
self.TestVar = 0
self.TheCount = 2
if self.TheCount ==2:
self.TestVar = 2
ThndClass()
def Getit(self):
print("called correctly")
print(self.TestVar)
return self.TestVar
def main():
app = QtGui.QApplication([])
mw = MainWindow()
sys.exit(app.exec_())
class ThndClass(QtGui.QWidget):
def __init__(self):
super(ThndClass, self).__init__()
self.initUI2()
def initUI2(self):
print("Class Called")
print(MainWindow.Getit(self))
if __name__ == '__main__':
main()
If I remove the 2nd Class call :
import sys
from PIL import Image
from PyQt4 import QtCore, QtGui
class MainWindow(QtGui.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.initUI()
def initUI(self):
self.TestVar = 0
self.TheCount = 2
if self.TheCount ==2:
self.TestVar = 2
self.Getit()
def Getit(self):
print("called correctly")
print(self.TestVar)
return self.TestVar
def main():
app = QtGui.QApplication([])
mw = MainWindow()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
This works correctly, but I want to be able to call def Getit() from another class and get my result. Or simply get a way to directly access self.TestVar from my other class.
When you call
MainWindow.Getit(self)
in ThndClass.initUI2, you are treating MainWindow and ThndClass interchangeably, when they do not have the same attributes. Here is an actual minimal example:
class Parent():
def __init__(self):
pass
class Child1(Parent):
def __init__(self):
super().__init__()
self.foo = "foo"
def method(self):
print(type(self))
print(self.foo)
class Child2(Parent):
def __init__(self):
super().__init__()
self.bar = "bar"
c1 = Child1()
Child1.method(c1) # pass Child1 instance to Child1 instance method
c2 = Child2()
Child1.method(c2) # pass Child2 instance to Child1 instance method
and full output:
<class '__main__.Child1'> # gets a Child1 instance
foo # first call succeeds
<class '__main__.Child2'> # gets a Child2 instance (which doesn't have 'foo')
Traceback (most recent call last):
File "C:/Python34/so.py", line 25, in <module>
Child1.method(c2)
File "C:/Python34/so.py", line 11, in method
print(self.foo)
AttributeError: 'Child2' object has no attribute 'foo' # second call fails
However, as it is not clear what exactly the code is supposed to be doing, I can't suggest a fix. I don't know why you create but don't assign a ThndClass instance in MainWindow.initUI, for example.
Here is one possible fix; pass a Child1 instance to Child2.__init__, then use it either as an argument to Child2.method:
class Child2(Parent):
def __init__(self, c1): # provide Child1 instance as parameter
super().__init__()
self.bar = "bar"
self.method(c1) # pass instance to Child2.method
def method(self, c1):
c1.method() # call Child1.method with c1 as self parameter
(Note that c1.method() is equivalent to Child1.method(c1).)
or make it an instance attribute:
class Child2(Parent):
def __init__(self, c1): # provide Child1 instance as parameter
super().__init__()
self.bar = "bar"
self.c1 = c1 # make Child1 instance a Child2 instance attribute
self.method() # now no argument needed
def method(self):
self.c1.method() # call Child1.method with c1 as self parameter
(Note that self.c1.method() is equivalent to Child1.method(self.c1).)
In use (either way):
>>> c1 = Child1()
>>> c2 = Child2(c1)
<class '__main__.Child1'> # Child1.method gets a Child1 instance
foo # and is called successfully
Thank's to your help jonrsharpe here's my working code :)
import sys
from PIL import Image
from PyQt4 import QtCore, QtGui
class MainWindow(QtGui.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.initUI()
def initUI(self):
self.TestVar = 0
self.TheCount = 2
if self.TheCount ==2:
self.TestVar = 2
Themain = self
ThndClass(Themain)
def Getit(self):
print("called correctly")
print(self.TestVar)
return self.TestVar
def main():
app = QtGui.QApplication([])
mw = MainWindow()
sys.exit(app.exec_())
class ThndClass(QtGui.QWidget):
def __init__(self, Themain):
super(ThndClass, self).__init__()
self.Themain = Themain
self.initUI2()
def initUI2(self):
print("Class Called")
print(self.Themain.Getit())
if __name__ == '__main__':
main()
All working good now : ) Thanks you very much !
I have:
cdef class BaseClass():
def __cinit__(self,char* name):
print "BaseClass __cinit__()"
#...
def __dealloc__():
print "BaseClass __dealloc__()"
#...
cdef class DerClass(BaseClass):
def __cinit__(self,char* name,int n):
print "DerClass __cinit__()"
#...
def __dealloc__():
print "DerClass __dealloc__()"
#...
when i call the DerClass in cyhton happen that the construcor of the BaseClass is called automatically,what it has to print is:
BaseClass __cinit__()
DerClass __cinit__()
DerClass __dealloc__()
BaseClass __dealloc__()
but it does not,it crash ones that i call the DerClass('Ciao').
why does happen so and how can i avoid calling the cinit of BaseClass.
Thank you!
The above answer may not pose quite the best solution. Reading the section "Initialisation methods: __cinit__() and __init__()" of the link above gives this information:
If your extension type has a base type, the __cinit__() method of the base type is automatically called before your __cinit__() method is called; you cannot explicitly call the inherited __cinit__() method.
and
If you anticipate subclassing your extension type in Python, you may find it useful to give the __cinit__() method * and ** arguments so that it can accept and ignore extra arguments.
So my solution would be to just replace the arguments of __cinit()__ in BaseClass so that a variable number of arguments can be passed to any derived class:
cdef class BaseClass:
def __cinit__(self, *argv):
print "BaseClass __cinit__()"
#...
def __dealloc__(self):
print "BaseClass __dealloc__()"
#...
cdef class DerClass(BaseClass):
def __cinit__(self,char* name, int n):
print "DerClass __cinit__()"
#...
def __dealloc__(self):
print "DerClass __dealloc__()"
#...
See here for an explanation of the *args variable in python
Well, you are right that you should see the cinit method called on your parent class. It says so right here in the docs.
http://docs.cython.org/src/userguide/special_methods.html
Here is what I tried using:
cdef class BaseClass:
def __cinit__(self,char* name):
print "BaseClass __cinit__()"
#...
def __dealloc__(self):
print "BaseClass __dealloc__()"
#...
cdef class DerClass(BaseClass):
def __cinit__(self,char* name,int n):
print "DerClass __cinit__()"
#...
def __dealloc__(self):
print "DerClass __dealloc__()"
#...
It compiled but it gave me this error when I tried to run it:
mike#computer:~/testing$ python runner.py
DerClass __dealloc__()
BaseClass __dealloc__()
Traceback (most recent call last):
File "runner.py", line 4, in <module>
DerClass('Ciao', 1)
File "test.pyx", line 2, in test.BaseClass.__cinit__ (test.c:488)
def __cinit__(self,char* name):
TypeError: __cinit__() takes exactly 1 positional argument (2 given)
mike#computer:~/testing$
So I changed BaseClass.cinit to also take the "int n" parameter that DerClass.cinit does:
cdef class BaseClass:
def __cinit__(self, char * name, int n):
print "BaseClass __cinit__()"
#...
def __dealloc__(self):
print "BaseClass __dealloc__()"
#...
cdef class DerClass(BaseClass):
def __cinit__(self,char* name,int n):
print "DerClass __cinit__()"
#...
def __dealloc__(self):
print "DerClass __dealloc__()"
#...
And now it seems to work fine:
mike#computer:~/testing$ python runner.py
BaseClass __cinit__()
DerClass __cinit__()
DerClass __dealloc__()
BaseClass __dealloc__()
mike#computer:~/testing$
Here is my runner.py file:
from test import *
if __name__ == "__main__":
DerClass('Ciao', 1)