class x():
def __init__(self):
self.z=2
class hi():
def __init__(self):
self.child=x()
f=hi()
print f.z
I want it to print 2.
Basically I want to forward any calls to that class to another class.
The simplest approach is implementing __getattr__:
class hi():
def __init__(self):
self.child=x()
def __getattr__(self, attr):
return getattr(self.child, attr)
This has certain disadvantages, but it might work for your limited use case. You might want to implement __hasattr__ and __setattr__ as well.
The Python syntax is:
class hi(x):
To say that hi inherit (should be a child of) x.
.
Note: in order for hi to have property z (since this is in hi's __init__) x.__init__ needs to be explicitly run in x. That is,
class hi(x):
def __init__(self):
x.__init__(self)
Related
I've got some code where I need to refer to a superclass when defining stuff in a derived class:
class Base:
def foo(self):
print('foo')
def bar(self):
print('bar')
class Derived_A(Base):
meth = Base.foo
class Derived_B(Base):
meth = Base.bar
Derived_A().meth()
Derived_B().meth()
This works, but I don't like verbatim references to Base in derived classes. Is there a way to use super or alike for this?
You can't do that.
class keyword in Python is used to create classes which are instances of type type. In it's simplified version, it does the following:
Python creates a namespace and executes the body of the class in that namespace so that it will be populated with all methods and attributes and so on...
Then calls the three-arguments form of type(). The result of this call is your class which is then assign to a symbol which is the name of your class.
The point is when the body of the class is being executed. It doesn't know about the "bases". Those bases are passed to the type() after that.
I also explained the reasons why you can't use super() here.
Does this work for you?
class Base:
def foo(self):
print('foo')
def bar(self):
print('bar')
class Derived_A(Base):
def __init__(self):
self.meth = super().foo
class Derived_B(Base):
def __init__(self):
self.meth = super().bar
a = Derived_A().meth()
b = Derived_B().meth()
You'll need to lookup the method on the base class after the new type is created. In the body of the class definition, the type and base classes are not accessible.
Something like:
class Derived_A(Base):
def meth(self):
return super().foo()
Now, it is possible to do some magic behind the scenes to expose Base to the scope of the class definition as its being executed, but that's much dirtier, and would mean that you'd need to supply a metaclass in your class definition.
Since you want "magic", there is still one sane option we can take before diving into metaclasses. Requires Python 3.9+
def alias(name):
def inner(cls):
return getattr(cls, name).__get__(cls)
return classmethod(property(inner))
class Base:
def foo(self):
...
class Derived_A(Base):
meth = alias("foo")
Derived_A().meth() # works
Derived_A.meth() # also works
Yes, this does require passing the method name as a string, which destroys your IDE and typechecker's ability to reason about it. But there isn't a good way to get what you are wanting without some compromises like that.
Really, a bit of redundancy for readability is probably worth it here.
First day learning Python, please excuse the basic question.
Assuming I have been given an object which contains an unimplemented method that I need to implement, e.g:
class myclass():
def __init__(self)
self.unimplementedmethod = False
What is the correct way to implement this in an instantiated object? I do not want to alter the base class in any way.
I have experimented and found the following code seems to work, but is it correct/good style?
def methodimplementation():
print("method called")
myobject = myclass()
myobject.unimplementedmethod=methodimplementation
Is this the right path? Or should I be doing something different like perhaps creating a derived class first, implementing the methods in it, and then instantiating an object based on the derived class? What is best practice?
You need to subclass the base class:
class myclass():
def some_method():
raise NotImplementedError
class my_subclass(myclass):
def some_method():
print("method called")
You want to create a abstract base class. For that, you need to inherit abc.ABCMeta in your base class. Then defining the method as abstract, you need to decorate it with #abstractmethod. For example:
from abc import ABCMeta, abstractmethod
class BaseClass(ABCMeta):
#abstractmethod
def my_method():
pass
Then you may create the child class as:
class MyChildClass(BaseClass):
def my_method():
print 'my method'
The good way is using subclasses, but if you can't do it, here is a way to access to self from a simple function not defined in a class:
class Bar:
def __init__(self):
pass
def foo(self):
try:
self._foo(self)
except AttributeError:
raise NotImplementedError
def set_foo(self, function):
setattr(self, '_foo', function)
def another_method(self):
print "Another method from {}".format(self)
def foo(self):
self.another_method()
bar = Bar()
bar.set_foo(foo)
bar.foo()
So, def foo(self) define a function with a single argument self, like a method. This function call a instance method another_method.
Bar.set_foo create a new attribute _foo in instance of Bar.
Finally, Bar.foo try to access to self._foo with self as argument. If _foo is do not exists, Bar.foo will raise a NotImplementedError as expected.
Like it you can access to self from foo without subclasses.
I am developing a system, which has a series of single multilevel inheritance hierarachy. one of the methods (applicable to all the classes) has to perform the same thing for most of the classes, which is to pass a list to its parent class.
I know that if one doesn't define a method in one of the inherited classes, its parents' methods are used. But when we use the super method, we need to mention the name of the class being called.
One method I know to achieve this is to redefine the method at every class with class name as argument. Is there any elegant method where I can define it once at the topmost parent, and then override it only when necessary?
The implementation right now looks like this
class a(object):
def __init__(self):
self.myL = list()
print 'hello'
class b(a):
def __init__(self):
super(b,self).__init__()
def resolve(self, passVal):
print passVal
self.myL.append(passVal)
super(b,self).resolve(passVal+1)
class c(b):
def __init__(self):
super(c,self).__init__()
def resolve(self, passVal):
print passVal
self.myL.append(passVal)
super(c,self).resolve(passVal+1)
Instead if I can define resolve in class a, and then all other classes inherit the method from it. I understand a will never be able to use it. but redefining the method seems a lot unnecessary extra work.
I have a function which return instances of the class Parent:
def generateParent():
do_stuff
return Parent(some_parameters)
Now I want to init a subclass of Parent with the results of a call to generateParent():
class Child(Parent):
def __new__():
return generateParent(some_other_parameters)
The problem is, when I override some methods from Parent in Child and then call them in instances of Child in my program, the original Parent method gets called instead of the new one from Child. Am I doing something wrong here? Am I using the correct design here for my task?
EDIT: I don't have access neither to Parent nor generateParent()
Solution(thanks to #Paul McGuire's answer):
class Child(object):
def __init__(self):
self.obj = generateParent()
def __getattr__(self, attr):
return getattr(self.obj, attr)
Since generateParent is not your code, then instead of inheritance, you might want to use containment and delegation. That is, instead of defining a subclass, define a wrapper class that contains the generated object, forwards method calls to it when needed, but can add new behavior or modified behavior in the wrapper.
In this question, the OP had a similar situation, having a class generated in a libary, but wanting to extend the class and/or modify some behavior of the class. Look at how I added a wrapper class in that question, and you might consider doing something similar here.
Here's one way to do it:
def generateChild(params):
p = generateParent(params)
p.__class__ = Child
return p
class Child(Parent):
# put method overrides etc here
childinstance = generateChild(some_params)
Perhaps you want generateParent to be able to make instances of other classes:
def generateParent(cls=Parent):
do_stuff
return cls(some_parameters)
Now this will make a Child object:
child = generateParent(Child)
Or perhaps you want Parent and all of its derived classes to use common initialization code?
class Parent(object):
def __init__(self):
do_stuff
# init from some_parameters
class Child(Parent):
# blah..
Make your Child object able to copy information from a created Parent object:
class Child(Parent):
def __init__(self):
model_parent = generateParent()
self.a = model_parent.a
self.b = model_parent.b
# etc.
Is there no magic python way of accessing the instance of the class that has a reference to the current self inside it?
ie:
class A(object):
def __init__(self):
self.B = B()
def say_hi(self):
print "Hi"
class B(object)
def __init__(self):
__get_owner_ref__.say_hi()
A()
get_owner_ref being the magic bullet that does not exist.
Is there a feature in python for this behaviour?
Yes I know I could pass a reference in to the constructor, but I'm looking for a more elegant solution.
No, You'd have to do something like this
class A(object):
def __init__(self):
self.B = B(parent=self)
def say_hi(self):
print "Hi"
class B(object)
def __init__(self, parent):
self.parent = parent # you don't need to do this, but it might be a good idea
parent.say_hi()
A()
On the second thought, what you're looking for pretty closely resembles descriptors. Consider:
class Agent(object):
def __get__(self, obj, objtype):
print 'Agent %s called from %s ' % (id(self), obj.name)
class X(object):
agent = Agent()
def __init__(self, name):
self.name = name
a = X('Foo')
a.agent
b = X('Bar')
b.agent
Here the agent is attached to two different instances and "knows" each time which instance wants to talk to him.
No, there is no nice way of doing this. Pass a reference in to the initializer.
To preclude questions, it's probably possible in most cases to find the owner heuristically by inspecting the stack, something like in this question. But it will be fragile, buggy and difficult to understand. And it goes against the "explicit > implicit" philosophy.
As far as I know such a feature does not exist. Also, passing it in as reference to the constructor and calling self.parent.say_hi() is much more explicit and (indeed) elegant. And explicit is better than implicit or using magic language features.
Technically, you can use sys._getframe:
class B(object):
def __init__(self):
import sys
a = sys._getframe(1).f_locals['self']
a.say_hi()
But you should not do that. It's bound to lead to confusion, will break on new Python implementations, will complicate debugging, and is prone to break.There's a reason why sys._getframe is listed in 5 Years of Bad Ideas.
Instead, pass a reference, either to the parent object, or to the say_hi method.