So I am trying to create a public method that can be called by class a so that it edits a data item in class b.
class aClass():
def __init__(self):
aVariable = 1
class aNotherClass():
def aMethod(self):
aFunction(5)
def aFunction(aNumber):
instance1.aVariable = aNumber
instance1 = aClass()
instance2 = aNotherClass()
instance2.aMethod
However, when I call instance1 in aFunction, python tells me it isn't defined. If I want to change aVariable in aClass, what should aFunction() say?
I think you may forget the self when you define a class method.
refer to: https://docs.python.org/2/tutorial/classes.html#class-objects
class aClass():
def __init__(self):
aVariable = 1
class aNotherClass():
def aMethod(self):
aFunction(5)
def aFunction(aNumber):
instance1.aVariable = aNumber
instance1 = aClass()
instance2 = aNotherClass()
instance2.aMethod()
Related
Imagine a parent class which has a mangled attribute, and a child class:
class Foo:
def __init__(self):
self.__is_init = False
async def init(self):
# Some custom logic here, not important
self.__is_init = True
class Bar(Foo):
...
# Create class instance.
bar = Bar()
# How access `__is_init` of the parent class from the child instance?
How can I get a __is_init value from a parent (Foo) class?
Obviously, I can bar._Foo__is_init in this example, but the problem is that class name is dynamic and I need a general purpose solution that will work with any passed class name.
The solution I see now is iterating over parent classes, and building a mangled attribute name dynamically:
from contextlib import suppress
class MangledAttributeError(Exception):
...
def getattr_mangled(object_: object, name: str) -> str:
for cls_ in getattr(object_, "__mro__", None) or object_.__class__.__mro__:
with suppress(AttributeError):
return getattr(object_, f"_{cls_.__name__}{name}")
raise MangledAttributeError(f"{type(object_).__name__} object has no attribute '{name}'")
Checking that this works:
class Foo:
def __init__(self):
self.__is_init = False
async def init(self):
self.__is_init = True
class Bar(Foo):
def __init__(self):
super().__init__()
bar = Bar()
is_init = getattr_mangled(bar, "__is_init")
print(f"is_init: {is_init}") # Will print `False` which is a correct value in this example
class Foo:
def __init__(self):
self.__is_init = False
async def init(self):
self.__is_init = True
class Bar(Foo):
def getattr_mangled(self, attr:str):
for i in self.__dict__.keys():
if attr in i:
return getattr(self,i)
# return self.__dict__[i] #or like this
bar = Bar()
print(bar.getattr_mangled('__is_init')) #False
if there is a need in __init__ in Bar we should of course initiate Foo's init too by: super().__init__()
When Foo's init is run, self namespace already has attribute name we need in the form we need it (like_PARENT_CLASS_NAME__attrname).
And we can just get it from self namespace without even knowing what parent class name is.
How to use variable outside of function which is define inside of function?
And Function should declare in class.
class A:
def aFunction(self):
aVariable = "Hello"
Now here I want to use that aVariable
If you want to use this variable within the class A, how about using an instance variable?
class A:
def aFunction(self):
self.aVariable = "Hello"
Now you can use self.aVariable in another function of the same class
There are definitely more options that maybe others will provide, but these are the options I have come up with.
Use return
class A:
def aFunction(self):
aVariable = "Hello"
return aVariable
obj = A()
var = obj.aFunction()
print(var)
use global
class A:
def aFunction(self):
global aVariable
aVariable = "Hello"
obj = A()
obj.aFunction()
print(aVariable)
You can use self to your advantage
class A:
def __init__(self):
self.aVariable = None
def aFunction(self):
self.aVariable = "Hello"
obj = A()
obj.aFunction()
print(obj.aVariable)
To use a variable from a class outside of the function or entire class:
class A:
def aFunction(self):
self.aVariable = 1
def anotherFunction(self):
self.aVariable += 1
a = A() # create instance of the class
a.aFunction() # run the method aFunction to create the variable
print(a.aVariable) # print the variable
a.anotherFunction() # change the variable with anotherFunction
print(a.aVariable) # print the new value
There are several methods you can try.
class A:
def aFunction(self):
self.aVariable = "Hello"
# you can access self.aVariable in the class
class A:
def aFunction(self):
aVariable = "Hello"
return aVariable
# use self.aFunction() whenever you need this variable
The return keyword will return the value provided. Here, you have provided self.aVariable. Then, you can assign the value to a variable outside the class and print the variable.
class A:
def aFunction(self):
self.aVariable = "Hello"
return self.aVariable
a = A() #==== Instantiate the class
f=a.aFunction() #==== Call the function.
print(f)
This will print: Hello
I want to access username variable in class b who created in class a.
class a():
def __init__(self):
self.username = "amirhossein"
self.passwd = 1234
class b():
def __init__(self):
self.amir = a.username
print(self.amir)
b()
this code give me this error:
AttributeError: type object 'a' has no attribute 'username'
what should I do?
In order to access variables that are in a class, you either need to make them class variables, or create an instance of that class and access that instance's variables.
Here's how you'd use class variables:
class a():
username = "amirhossein"
passwd = 1234
def __init__(self):
pass
class b():
def __init__(self):
self.amir = a.username
print(self.amir)
b()
And here's how you could do it with instances:
class a():
def __init__(self):
self.username = "amirhossein"
self.passwd = 1234
class b():
def __init__(self, a_instance):
self.amir = a_instance.username
print(self.amir)
b(a())
Both of them have the same output - amirhossein.
Helpful reading: Class vs Instance Variables
I have two classes (ClassA and ClassB) and ClassA contains one object, b, that is an instance of ClassB. The question is that I can't call the b's method in Class A.
class ClassB(object):
def __init__(self):
print('Class B init ...')
def show(self):
print('Showing class b')
class ClassA(object):
#__classb = ClassB()
def __init__(self, classb):
print('Class A init ...')
__classb = classb
def show(self):
__classb.show() # <=== I just want to do this!
b = ClassB()
a = ClassA(b)
a.show()
I expect the result should be:
Class B init ...
Class A init ...
Showing class b
But I meet the problem as this image shows:
How can I fix it?
By doing __classb = classb you are only defining a local __classb variable in the __init__ method.
If you want __classb to be an instance attribute you will need to use self:
self.__classb = classb
And then:
def show(self):
self.__classb.show()
You should create a attribute for a instance of class B in class A like that self.__classb.
Following code
class ClassB(object):
def __init__(self):
print('Class B init ...')
def show(self):
print('Showing class b')
class ClassA(object):
def __init__(self, classb):
print('Class A init ...')
self.__classb = classb
def show(self):
self.__classb.show() # <=== I just want to do this!
b = ClassB()
a = ClassA(b)
a.show()
I have the following code segment :
class A:
def __init__(self):
self.state = 'CHAT'
def method1(self):
self.state = 'SEND'
def printer(self):
print self.state
class B(A):
def method2(self):
self.method1()
print self.state
ob_B = B()
ob_A = A()
ob_B.method2()
ob_A.printer()
This gives me the output :
SEND
CHAT
I want it to print :
SEND
SEND
That is, when B.method2 is modifying self.state by calling self.method1, I want it to modify the already existing value of self.state = 'CHAT' in A's instance. How can I do this?
The instance is passed as the first argument to each of your methods, so self is the instance. You are setting instance attributes and not class variables.
class A:
def __init__(self):
A.state = 'CHAT'
def method1(self):
A.state = 'SEND'
def printer(self):
print A.state
class B(A):
def method2(self):
self.method1()
print B.state
ob_B = B()
ob_A = A()
ob_B.method2()
ob_A.printer()
SEND
SEND
ob_B = B()
ob_A = A()
ob_B.method2()
ob_A.printer()
You need to call ob_B.method2() -- without the parentheses that statement is just a reference to the function and doesn't actually call it.
You can call the printer() method by using object of B so that you will get the updated value.
ob_B = B()
ob_A = A()
ob_B.method2()
ob_B.printer()