How can I get the name of a child class? - python

class Foo():
class Bar(Foo):
A method of Foo have to know the name of the child class. How can I get the name?
In this example I want to get "Bar".
I'm sorry for my english.

If it needs to be an instancemethod:
def meth(self): print self.__class__
If you want a classmethod:
#classmethod
def meth(cls): print cls

Extremely old, but since i stumbled upon this by duckduck'ing the topic...
Consider you have:
class Foo():
pass
class Bar(Foo):
pass
Python 3
my_bar = Bar()
type(my_bar).__name__
# Bar
Python 2
my_bar = Bar()
my_bar.__class__.__name__
# Bar

Related

How can we override the constructor while still using the `class` keyword? [duplicate]

This question already has an answer here:
__metaclass__ in Python 3
(1 answer)
Closed 3 years ago.
Two notable ways to create a class are shown below:
class Klass:
pass
Klass = type("Klass", tuple(), dict())
I would like to override the constructor (__call__) while still using the class keyword instead of doing something else, like directly calling type. I really do want to override (__call__), not __init__
My failed attempts are shown below:
Attempt 1
class Foo:
#classmethod
def __call__(*args):
print("arr har")
return super(type(args[0]), args[0]).__call__(*args)
instance = Foo()
# did not print "arr har"
Attempt 2
class BarMeta(type):
def __call__(*args):
print("hello world")
return super(type(args[0]), args[0]).__call__(*args[1:])
Attempt 2A
class Bar:
__metaclass__ = BarMeta
instance = Bar()
# did not print "hello world"
Attempt 2B
Baz = BarMeta("Baz", tuple(), dict())
instance = Baz()
# Did print "hello world," but we weren't able to use the `class` keyword to create `Baz`
All credit does to Aran-Fey, who posted the answer as a comment, instead of as an answer:
class BarMeta(type):
def __call__(*args):
print("hello world")
return super(type(args[0]), args[0]).__call__(*args[1:])
class Bar(metaclass=BarMeta):
pass
instance = Bar()

Inheriting from variable class in python

I have a class foo that inherits from bar. However I also want to have the option when initializing foo to have it inherit from wall instead of bar. I am thinking something like this:
class Foo():
def __init__(self, pclass):
self.inherit(pclass)
super().__init__()
Foo(Bar) # child of Bar
Foo(Wall) # child of Wall
Is this possible in Python?
It's not really possible easily, because classes are defined at the time of executing the class block, not at the time of creating an instance.
A popular design pattern to use instead would be to put the common code into a mixin:
class FooMixin:
# stuff needed by both Foo(Bar) and Foo(Wall)
class FooBar(FooMixin, Bar):
...
class FooWall(FooMixin, Wall):
...
Then you can use some sort of factory function:
def make_foo(parent, *init_args, **init_kwargs):
if parent is Bar:
Foo = FooBar
elif parent is Wall:
Foo = FooWall
return Foo(*init_args, **init_kwargs)

Create an object of the same class within the class

I want to have an object of a class within a class, because I need to pass it to a method, similarly to the example below. I would like the example below to print out 1, or fooObj.fooNum, but I keep getting a NameError: name 'foo' is not defined.
class bar:
def fooDef(self, fooObj):
print fooObj.fooNum
class foo:
fooNum = 1
b = bar()
f = foo()
b.fooDef(f)
Please, can you be more specific about what you are trying to do?
The error you see is normal, because the code immediately below class foo will be executed during the definition of foo and therefore the class is not defined yet.
If I understand well you want to define some method foobar of the class foo, which will use a foo instance. The correct procedure would then be
class foo:
def foobar(self,):
f = foo()
...
Again, with more details about what you are trying to do it would be easier to help you.
Although it's unclear what you are asking, but the following changes do what you want to have.
But the code uses the instance of foo() not the class:
class bar:
def fooDef(self, fooObj):
print fooObj.fooNum
class foo:
def __init__(self):
self.fooNum = 1
b = bar()
f = self
b.fooDef(f)
f = foo()
Prints:
1

Python: looking for a short-hand way to setup setters/getters for lots of variables

I have one class (Bar) embedded inside another class (Foo).
class Foo():
class Bar():
def __init__(self):
self.a = 1
self.b = 2
...
self.z = 26
def __init__(self):
self.bar = Bar()
To access the attributes of class Bar, the user would need to the following:
>>> f = Foo()
>>> f.bar.a
1
How can I setup a short dot notation so that users can use BOTH:
>>> f.bar.a
1
and
>>> f.a
1
In my example, I'm trying to demonstrate that Bar class has a lot of variables. So I don't want to write a getter/setter for each one manually. So I was thinking to use the property() in a for loop like this:
def __init__(self):
self.bar = Bar()
# Allow shorter dot notation
for parm in self.bar.__dict__:
setattr(self, i, getattr(bar, i))
self.i = property(...)
But I'm unsure how to use property in this context without manually writing several setter functions.
Any suggestions on how to allow access to both shorter and longer notations?
That's what the __getattr__hook is ideally suited for:
class Foo:
# ...
def __getattr__(self, name):
return getattr(self.bar, name)
__getattr__ is only called for attributes that are missing; so only attributes that are not already present on instances of Foo() are passed to Foo().__getattr__(). The getattr() function then lets you use the same attribute name on self.bar; if the attribute doesn't exist there either, an AttributeError is thrown, as would be expected.

How do I pass variables between class instances or get the caller?

class foo():
def __init__(self)
self.var1 = 1
class bar():
def __init__(self):
print "foo var1"
f = foo()
b = bar()
In foo, I am doing something that produces "var1" being set to 1
In bar, I would like to access the contents of var1
How can I access var1 in the class instance f of foo from within the instance b of bar
Basically these classes are different wxframes. So for example in one window the user may be putting in input data, in the second window, it uses that input data to produce an output. In C++, I would have a pointer to the caller but I dont know how to access the caller in python.
As a general way for different pages in wxPython to access and edit the same information consider creating an instance of info class in your MainFrame (or whatever you've called it) class and then passing that instance onto any other pages it creates. For example:
class info():
def __init__(self):
self.info1 = 1
self.info2 = 'time'
print 'initialised'
class MainFrame():
def __init__(self):
a=info()
print a.info1
b=page1(a)
c=page2(a)
print a.info1
class page1():
def __init__(self, information):
self.info=information
self.info.info1=3
class page2():
def __init__(self, information):
self.info=information
print self.info.info1
t=MainFrame()
Output is:
initialised
1
3
3
info is only initialised once proving there is only one instance but page1 has changed the info1 varible to 3 and page2 has registered that change.
No one has provided a code example showing a way to do this without changing the init arguments. You could simply use a variable in the outer scope that defines the two classes. This won't work if one class is defined in a separate source file from the other however.
var1 = None
class foo():
def __init__(self)
self.var1 = var1 = 1
class bar():
def __init__(self):
print var1
f = foo()
b = bar()
Same as in any language.
class Foo(object):
def __init__(self):
self.x = 42
class Bar(object):
def __init__(self, foo):
print foo.x
a = Foo()
b = Bar(a)
Alternatively you could have a common base class from which both derived classes inherit the class variable var1. This way all instances of derived classes can have access to the variable.
Something like:
class foo():
def __init__(self)
self.var1 = 1
class bar():
def __init__(self, foo):
print foo.var1
f = foo()
b = bar(foo)
You should be able to pass around objects in Python just like you pass around pointers in c++.
Perhaps this was added to the language since this question was asked...
The global keyword will help.
x = 5
class Foo():
def foo_func(self):
global x # try commenting this out. that would mean foo_func()
# is creating its own x variable and assigning it a
# value of 3 instead of changing the value of global x
x = 3
class Bar():
def bar_func(self):
print(x)
def run():
bar = Bar() # create instance of Bar and call its
bar.bar_func() # function that will print the current value of x
foo = Foo() # init Foo class and call its function
foo.foo_func() # which will add 3 to the global x variable
bar.bar_func() # call Bar's function again confirming the global
# x variable was changed
if __name__ == '__main__':
run()

Categories