I'm getting this error:
unbound method hello() must be called with A instance as first argument(got nothing instead)
import B
class A():
#staticmethod
def newHello():
A.oldHello() # Here the error
print ' world'
def inject(self):
A.oldHello = B.hello
B.hello = A.newHello
A().inject()
B.hello()
B.py contain only a function "hello" that print "hello"
def hello():
print 'hello'
Thanks in advance
A.oldhello() is not static. So in B's hello function is referencing A's nonstatic oldhello statically. A does in fact need an instance. I'm not too good with the decorators and how they work but maybe try declaring oldhello in the class before the function and calling it #staticmethod. I don't know if the staticness carries over if you override the method.
Try this:
class B():
def hello(self):
print "hello"
class A():
#staticmethod
def newHello(self):
A.oldHello(self) # Here the error
print ' world'
def inject(self):
A.oldHello = B.hello
B.hello = A.newHello
A().inject()
B().hello()
Related
I am trying to access the object of class b (self.variable) inside another class a, after class b has been inherited by class c and calls an instance of class a. I don't know how to access the instance of class b that was created during the inheritance init. Additionally, a needs to inherit from class k.
Optimal would be if I could access self.variable inside class a and further pass it on without explicitly referring to the instance of class b (namely, just calling it with self.variable instead of b.variable) and without changing the values I already assigned to the variables in class c (so no re-initializing it)
I'd appreciate any help, I've been at this for hours.
class k(object):
def __init__(self):
pass
class b(object):
def __init__(self):
self.variable = 1
class c(b):
def __init__(self):
b.__init__(self)# b is inherited from & initialized
# alternative for inheritance
#super(c,self).__init__()
print("init(): " + str(self.variable))
def run(self):
self.variable = 2
print("run(): " + str(self.variable))
a()# here I need to pass the instance of b
class a(k):
def __init__(self):
k.__init__(self)# a() needs to inherit from k()
# ERROR: cannot access variables of b()
print("a(): " + str(self.variable))
if __name__ == "__main__":
c().run()
I think I figured out how to do it.
If passing the instance is enough, this would work:
class k(object):
def __init__(self):
pass
class b(object):
def __init__(self):
self.bb = self.bb()
class bb:
def __init__(self):
self.variable = 1
class c(b):
def __init__(self):
b.__init__(self)# b is inherited from & initialized
# alternative for inheritance
#super(c,self).__init__()
print("init(): " + str(self.bb.variable))
def run(self):
self.bb.variable = 99
print("run(): " + str(self.bb.variable))
a(self)# pass instance of b
class a(k):
def __init__(self, bInstance):
k.__init__(self)# a() needs to inherit from k()
print("a(): " + str(bInstance.bb.variable))
if __name__ == "__main__":
c().run()
As I understand it, if I want to get there via self I'd need class a to inherit from class c and class c inherits and initializes class b, the call at the end is just a() (which does what I need it to do, since a inherits everything I need):
class k(object):
def __init__(self):
pass
class b(object):
def __init__(self):
self.bb = self.bb()
class bb:
def __init__(self):
self.variable = 1
class c(b):
def __init__(self):
b.__init__(self)# b is inherited from & initialized
# alternative for inheritance
#super(c,self).__init__()
print("init(): " + str(self.bb.variable))
def run(self):
self.bb.variable = 99
print("run(): " + str(self.bb.variable))
class a(k,c):
def __init__(self):
k.__init__(self)# a() needs to inherit from k()
c.__init__(self)
print("a(): " + str(self.bb.variable))
self.run()
print("a() #2: " + str(self.bb.variable))
if __name__ == "__main__":
a()
Class test:
a=10
b=20
Def c(self,a,b):
Return a+b
Print test.a
#10
Print test.b
#20
Print test.c(1,2)
#Error unbound method c()
Plz point out were I am going wrong I am beginner in terms of using classes
Sorry for the upper cases in my code .I had to type it out on my tiny mobile screen.
You have tried to access method inside class directly.
To call method inside class need to create instance of class
following programming will work
class Test:
a = 10 # class variable
b = 20 # class variable
def c(self,a,b):
return a+b
print Test.a
print Test.b
obj = Test()
print obj.c(1,2) #3
# class is lowercase
# class names are by convention uppercase (Test)
class Test:
# def is lowercase
def c(self, a, b):
# return is lowercase
return a + b
# Create a new instance of the Test class
test = Test()
print test.c(1, 2) # prints 3
Here is a minimal example:
This works in both python 3.5 and 2.7:
class A(object):
def __init__(self, foo):
self._foo = foo
class B(A):
def __init__(self, foo):
A.__init__(self, foo=foo)
b = B(1)
Change line:
A.__init__(self, foo=foo)
to
A.__init__(self=self, foo=foo)
In python 3.5 works without problems, but in python 2.7 you will receive the following error:
Traceback (most recent call last):
File "self_key.py", line 9, in <module>
b = B(1)
File "self_key.py", line 7, in __init__
A.__init__(self=self, foo=foo)
TypeError: unbound method __init__() must be called with A instance as first argument (got nothing instead)
Is self as keyword argument forbidden in python 2.7 or is this a bug?
Update
I'm aware that python will use the first parameter of a bound function to pass the reference to the object from which has been called. I also know that the __init__ function expects that this parameter is an instance of the class. In this case A.__init__ is unbound so we must provide that parameter manually.
When I asked about self as keyword argument forbidden I'm speaking about self as "the first parameter of __init__", which is supposed to receive a reference of the object to initialize. The name of the variable itself doesn't matter. We can perfectly change the name to this:, for example:
class A(object):
def __init__(this, foo):
this._foo = foo
class B(A):
def __init__(self, foo):
A.__init__(this=self, foo=foo)
b = B(1)
And it will be the same.
My question is why when calling the function we can perfectly specify that parameter as a positional argument (A.__init__(self, foo=foo)) but when we try to pass it as a keyword argument (A.__init__(this=self, foo=foo)) python 2.7 throws an error.
Actually, you don't have to use self keyword unless you're consistent. Check out this example, where I changed self to test :
class funcs():
def init(test, a, b):
test.a=a
test.b=b
def plus(test):
c = test.a + test.b
print"%d + %d = %d" %(test.a, test.b, c)
def minus(test):
c = test.a - test.b
print"%d - %d = %d" %(test.a, test.b, c)
obj = funcs()
obj.init(10, 6)
obj.plus()
obj.minus()
You can try to mix those instance name, so it won't be named self.
class A(object):
def __init__(a_obj, foo):
a_obj._foo = foo
class B(A):
def __init__(self, test, foo):
A.__init__(self, a_obj=test, foo=foo) # here you pass object of class B and actually another object of class B
a = A(2)
b = B(a, 1)
Giving output:
A.__init__(self, a_obj=test, foo=foo)
TypeError: __init__() got multiple values for keyword argument 'a_obj'
I'm not sure what actually you want to accomplish by passing those object like this. In your code, self in class A and self in class B are not the same objects.
I suppose that here: A.__init__(self=self, foo=foo) you are doing something like A_instance=B_instance (self=self)
Always use self for the first argument to instance methods.
Source: Python Documentation
Possible duplicates:
Is there a way to create subclasses on-the-fly?
Dynamically creating classes - Python
I would like to create a subclass where the only difference is some class variable, but I would like everything else to stay the same. I need to do this dynamically, because I only know the class variable value at run time.
Here is some example code so far. I would like FooBase.foo_var to be "default" but FooBar.foo_var to be "bar." No attempt so far has been successful.
class FooBase(object):
foo_var = "default"
def __init__(self, name="anon"):
self.name = name
def speak(self):
print self.name, "reporting for duty"
print "my foovar is '" + FooBase.foo_var + "'"
if __name__ == "__main__":
#FooBase.foo_var = "foo"
f = FooBase()
f.speak()
foobarname = "bar"
#FooBar = type("FooBar", (FooBase,), {'foo_var': "bar"})
class FooBar(FooBase): pass
FooBar.foo_var = "bar"
fb = FooBar()
fb.speak()
Many thanks
EDIT so I obviously have a problem with this line:
print "my foovar is '" + FooBase.foo_var + "'"
The accepted answer has self.foo_var in the code. That's what I should be doing. I feel ridiculous now.
What about this:
def make_class(value):
class Foo(object):
foo_var = value
def speak(self):
print self.foo_var
return Foo
FooBar = make_class("bar")
FooQux = make_class("qux")
FooBar().speak()
FooQux().speak()
That said, can't you make the value of foo_var be a instance variable of your class? So that the same class instantiated with different input behaves in different ways, instead of creating a different class for each of those different behaviours.
Facing the error as :
AttributeError: 'function' object has no attribute 'd'.
how to access the dictionary?
code:
class A:
#staticmethod
def test():
d = {}
d['a'] = 'b'
print d
#staticmethod
def test1():
d1 = {}
d1['a'] = 'c'
if (A.test.d['a'] == A.test1.d1['a']):
print "yes"
else:
print "Oh No!!"
A.test()
A.test1()
Check out this on the matter of static variables in Python.
You should be able to sort it out using A.d and A.d1 whenever you wish to use the static variables. Note that, as you have them, they are local to test and test1, respectively. If you want them to be static, you have to declare them inside the class scope, but not within any function definition.