I have a method in a dictionary as a class attribute;
class parentClass(object):
pass
class childClass(parentClass):
a = {'meth': my_meth}
def my_meth(self, var):
print(var)
inp = input()
# User enters 'meth'
childClass.a[inp]('test')
When I run the program I get the error;
NameError: name 'my_meth' is not defined
I have read functions are first class citizens in python. How can I assign a method as a value in a dictionary so I can call it later with certain parameters?
class parentClass(object):
pass
class childClass(parentClass):
def __init__(self):
self.a = {'meth': self.my_meth}
def my_meth(self, var):
print(var)
c = childClass()
c.a['meth']('test')
You must define Instance Variables are in __init__.
The issue with your code is that you set the a as a static variable in the class, but the method in the class is not static and requires self parameter.
To solve this, you can make the a variable connected with the instances, by setting it in the __init__ method:
class parentClass(object):
pass
class childClass(parentClass):
def __init__(self):
self.a = {'meth': self.my_meth}
def my_meth(self , var):
print(var)
childClass().a['meth']('Helloworld')
Or the my_meth can be made static thus able to call it from the class itself, like:
class parentClass(object):
pass
class childClass(parentClass):
def my_meth(var):
print(var)
a = {'meth': my_meth}
x = childClass.a['meth']("Helloworld")
Related
Let's assume I have a class A and a class B.
class A:
def __init__(self):
self.variable1 = 1
self.variable2 = 'sometext'
class B:
def __init__(self, inst):
self = inst
print(self.__dict__.keys(), inst.__dict__.keys())
The print function returns
b = B(inst)
dict_keys(['variable1', 'variable2']) dict_keys(['variable1', 'variable2'])
However when I try
b.variable1
It returns the following error
AttributeError: 'B' object has no attribute 'variable1'
In my more complex code I need almost all variable from class A in class B.
I tried using class inheritance however I couldn't make it work with class methods and constructors.
Is there a reason why the above method doesn't work?
Thx
You're trying to overwrite self, but that only works while you're in the init. Instead, try assigning the inst to a variable of the class B:
class B:
def __init__(self, inst):
self.inst = inst
print(self.__dict__.keys(), inst.__dict__.keys())
Now you can access the variables of class A via:
inst = A()
b = B(inst)
b.inst.variable1
Not sure what you're trying to achieve here exactly, but you could also initiate the class A object inside the init of class B instead of passing the object to class B.
To use variable from class A in B you have to access to class A from B. Then execute class B
class A:
variable1 = 1
variable2 = 'sometext'
class B:
def __init__(self, inst=None):
self.f1 = A().variable1
self.f2 = A().variable2
def get_var(self):
print (self.f1)
B().get_var()
class DemoClass:
def __init__(self):
self.name = "Marko"
def some_method(self):
print(self.name)
print(self.name) # NameError: name 'self' is not defined ???
my_object = DemoClass()
Why does this happen? Didn't I initialize the self.name variable in the init method which I think it means that it should be accessable in the entire class?
class DemoClass:
def __init__(self):
self.name = "Marko"
def some_method(self):
print(self.name)
my_object = DemoClass()
my_object.some_method()
do like this bro then only you can print the name.
You call the print() function with a class attribute (name) as argument. Even though the attribute is defined when Python executes the print() line, the class attributes exist in the local scope of the class and are accessible only to the class members or through the class namespace (e.g. my_object.name in a different scope where my_object is defined).
class Person:
def _init_(self):
self.A=1
class Employee(Person):
def _init_(self):
print(A)
object1=Person()
object2=Employee()
There are actually multiple problems with that code, besides the misspelled constructor...
Your _init_ method should be __init__, otherwise it's not a constructor but just a method that happens to be called _init_, and thus never called.
You have to call the constructor of the super-class, or A will not be set, e.g. using super().__init__() or Person.__init__(self)
You have to use self.A to read the field A of the instance; otherwise it will look for a local variable called A
This should work:
class Person:
def __init__(self): # misspelled
self.A = 1
class Employee(Person):
def __init__(self): # misspelled
super().__init__() # call super constructor
print(self.A) # use self.A
I'm trying to access the methods of the class from which it was instantiated another class, I mean, accessing to the "parent" instance without creating a new instance of it.
class A():
def __init__(self):
...
b_instance = B()
...
class B():
def __init__(self):
...
def function1(self):
...
def function2(self):
C().run() # I need to use class C functionalities
...
class C():
def __init__(self):
...
def run(self):
classB.function1() #I can't access to these methods without instantiating again class B
# I have to execute:
>>> a = A()
>>> a.b_instance.function2()
Sorry if I have not explained well, is a bit confusing. If you need any clarification do not hesitate to ask.
EDIT.
In class C a specific handling of the execution of class B methods is done. Is not possible to instanciate again inside C because class B contains the initialization of hardware.
It's still not clear what exactly you're trying to achieve, but here's one fix:
class A():
def __init__(self):
...
b_instance = B()
...
class B():
def __init__(self):
...
def function1(self):
...
def function2(self):
C().run(self) # pass class B instance to C instance run method
...
class C():
def __init__(self):
...
def run(self, classB): # note additional parameter
classB.function1()
However, note that this represents a very high level of coupling between your various classes, which seems suspicious to me and may indicate a deeper flaw in your design.
This can access the class methods from other classes.
use instance method, class methods and static methods, if you are using various types of functins.
class A():
def __init__(self):
print 'in __init__'
self.b_instance = B() # making an instance of class
#self.b_instance.function2()
class B():
def __init__(self):
print 'in __init__, B'
#staticmethod
def function1():
print 'func1'
def function2(self):
C().run() # I need to use class C functionalities
# if you trying to access `run` method of `class C` make
# it instance bound method"""
class C():
def __init__(self):
pass
def run(self):
print 'in run'
B.function1() #I can't access to these methods without instantiating again class B
#you are passing class instance as `B` while calling function1
# so make it either classmethod `#classmethod` or `static method`
# I have to execute:
a = A()
a.b_instance.function2() # calling b_instance variable of class A
I'm trying to have a default instance of a class. I want to have
class Foo():
def __init__(self):
....
_default = Foo()
#staticmethod
def get_default():
return _default
However _default = Foo() leads to NameError: name 'Foo' is not defined
Foo does not exist until the class definition is finalized. You can easily refer to it after the class definition, though:
class Foo(object):
def __init__(self):
# ....
Foo.default_instance = Foo()
Note also that I have removed the superfluous getter method in favor of a plain old attribute.
You can also solve the problem with a decorator:
def defaultinstance(Class):
Class.default_instance = Class()
return Class
#defaultinstance
class Foo(object):
# ...
Or, gratuitously, with a metaclass:
def defaultmeta(name, bases, attrs):
Class = type(name, bases, attrs)
Class.default_instance = Class()
return Class
# Python 2.x usage
class Foo(object):
__metaclass__ = defaultmeta
# ...
# Python 3.x usage
class Foo(metaclass=defaultmeta):
# ...
When might you might want to use each method?
Use the post-definition class attribute assignment for one-offs
Use the decorator if you want the same behavior in a lot of unrelated classes and to "hide" the implementation of it (it's not really hidden, or even that complicated, here, though)
Use the metaclass if you want the behavior to be inheritable in which case it's not really gratuitous. :-)
You cannot refer to a class that doesn't yet exist. Within the class definition body, the Foo class is not yet created.
Add the attribute after the class has been created:
class Foo():
def __init__(self):
....
#staticmethod
def get_default():
return Foo._default
Foo._default = Foo()
Note that you also need to alter the get_default() static method; the class body doesn't form a scope, so you cannot reach _default as a non-local from get_default().
You are now, however, repeating yourself a lot. Reduce repetition a little by making get_default() a classmethod instead:
class Foo():
def __init__(self):
....
#classmethod
def get_default(cls):
return cls._default
Foo._default = Foo()
or create the default on first call:
class Foo():
def __init__(self):
....
#classmethod
def get_default(cls):
if not hasattr(cls, '_default'):
cls._default = cls()
return cls._default
You may lazily initialize your default instance.
class Foo(object):
_default = None
#staticmethod
def get_default():
if not Foo._default:
Foo._default = Foo()
return Foo._default