How can i separate methods of a class in separate files? - python

Let's say we have this class:
Class example:
def __init__(self):
self.var = 23
How can i access this variable within a function in another file by importing it in the main file?
def my_func():
pass
In fact i want the "my_func()" to be a method of the "example" class but in a separate file.

The idea is to split your class into two classes that have no data of their own—only methods—so although you inherit them, you never have to call super() on them. This classes are called "mixins"
_example.py
class Mixin:
def my_func(self):
print(self._b)
example.py
import _example
class Example(_example.Mixin):
def __init__(self):
self._a = 1
self._b = 2
self._c = 3
Now you can do:
ex = Example()
ex.my_func() # This will print "2" on console.
You can check different aproaches here

Related

Calling variable in one class file to another file in python3

Hi I'm a newbie in python programming. Please help me with this problem in python3:
pack.py
class one:
def test(self):
number = 100 ######I want to access this value and how?
print('test')
class two:
def sample(self):
print('sample')
another.py
from pack import *
class three:
def four(self):
obj = one()
print(obj.test())
###### I want to access the number value in this file and i don't know how #######
obj = three()
obj.four()
Here is an alternative
pack.py
class One:
def __init__(self):
self.number = 100
def test(self):
print('test')
class Two:
def sample(self):
print('Sample')
another.py
from pack import *
class Three:
def four(self):
self.obj = One().number
return self.obj
three = Three().four()
print(three)
By what seems to be your approach, you were using classes to access variables. It is better to instantiate variables in a constructor ( init method in class One). Then import the class and access it in another class of another file.
Also, it is a good practice to name classes beginning with uppercase letters. There are more possible ways but hope it helps.
number needs to be in a global scope, that means outside of a function definition (it shouldn't be indented)
if the variable is inside a function it is impossible to get it in another file
pack.py
number = 100
def test():
test.other_number = 999 # here we assigne a variable to the function object.
print("test")
another.py
import pack
pack.test()
print(pack.number)
print(test.other_number) # this only works if the function has been called once
Alternatively if you are using classes:
pack.py
class Someclass():
other_number = 999 # here we define a class variable
def __init__(self):
self.number = 100 # here we set the number to be saved in the class
def test(self):
print(self.number) # here we print the number
another.py
import pack
somclass_instance = pack.Someclass() # we make a new instance of the class. this runs the code in __init__
somclass_instance.test() # here we call the test method of Someclass
print(somclass_instance.number) # and here we get the number
print(Someclass.other_number) # here we retrieve the class variable

python dynamic multiple inheritance __init__

I am trying to write a plugin environment where I need to do multiple inheritances on an unknown number of classes. Therefore, I have opted to use the type class creation:
class A(object):
def __init__(self,s):
self.a="a"
def testA(self,x):
print(x)
class B(object):
def __init__(self,s):
self.b="b"
def testA(self,x):
print(x)
C = type('C', (A,B), {})
x= C("test")
print x.b
When I run the above code, I get the error:
AttributeError: 'C' object has no attribute 'b'
This is because only the init for class A is being run when the instance for class C is initialized. My question is how can I get the class C to have both the init for class A as well as the init for class B to run when an instance of class C is initialized. I do realize that if I had class C like the following it would work:
class C(A,B):
def __init__(self,s):
A.__init__(self,s)
B.__init__(self,s)
However, given that I need to have a dynamic list of classes inherited this will not work.
It seems you're using python 2 so I'm using this old python 2 super() syntax where you have to specify the class and the instance, although it would work in python 3 as well. In python 3 you could also use the shorter super() form without parameters.
For multiple inheritance to work is important that the grandparent class __init__ signature matches the signature of all siblings for that method. To do that, define a common parent class (MyParent in this example) whose __init__ has the same parameter list as all the childs. It will take care of calling the object's __init__ that doesn't take any parameter, for us.
from __future__ import print_function
class MyParent(object):
def __init__(self, s):
super(MyParent, self).__init__()
class A(MyParent):
def __init__(self, s):
self.a = "a"
super(A, self).__init__(s)
def testA(self, x):
print(x)
class B(MyParent):
def __init__(self, s):
self.b = "b"
super(B, self).__init__(s)
def testA(self,x):
print(x)
C = type('C', (A, B), {})
x = C("test")
print(x.b)
You can define as many children to MyParent as you want, and then all __init__ methods will be called, provided you used super() correctly.

Python: Changing variables in another class from another

I have two files like the following
file1.py
class A:
def method1:
a = 5
file2.py
class B
def method2:
from file1 import A
a = 10
Forget the logic, its just an example. I wish to manipulate the value of a in my code. When I do this it gives me an error saying
"global name a is not defined". How can I solve this problem. Any help will be appreciated
The way you defined a it is a local variable to that method. What you want is self.a...
file1.py
class A:
def method1:
self.a = 5
file2.py
from file1 import A
class B:
def method2:
objecta = A()
objecta.a = 10
But reading your comments, what you actually want is something different.
Class A:
def __init__(self):
self.a = 5
def logic(self):
do some stuff...
Class B:
def solve(self):
first = A()
first.logic()
second = A()
second.logic()
etc...
The point of doing it with classes is that you can make multiple instances of the class. The init function creates an object of that class based on your baseline- so each time you make an A object, it will start out with your original settings.

Inheriting properties of a separate class in Python

I am instantiating a class inside another one:
class A(F):
def __init__(self):
return
b = B()
Class B also inherits class F:
class B(F):
def __init__(self):
return
There are properties of F which have been defined in class A, which I need to access inside class B. (a MySQL connection and a logging handler.)
I would like B to have the properties which have been set to F, when they were instantiated initially in A, so I can use the logging/mysql handlers inside B without re-instantiating them.
How can I go about this? Sorry if the question is unclear.
Put the stuff you want to share in F and both A and B will be able to share it. Eg
class F(object):
def useful(self):
pass
class A(F):
def something(self):
self.useful()
class B(F):
def something_else(self):
self.useful()

Question about python and classes

I have a base class and a few derived in Python:
class Base:
def Foo(self):
pass
# First derived class
class Der1(Base):
def OwnFoo(self):
# Do something 1
def OwnFoo2(self):
# Do something 2
def Foo(self):
# Do something 3
# Second derived class
class Der2(Base):
def OwnFoo(self):
# Do something 1
def OwnFoo2(self):
# Do something 2
def Foo(self):
# Do something 3
The question is:
I have some predefined code in Der1. Almost all functions from Der2 do the same. How can I write this with less code?
I can't add that code to the parent. Parent class shouldn't be touched.
For example, Der2.OwnFoo does the same as Der1.OwnFoo, maybe there is some construction in python just to call OwnFoo from first class and not to write that code again?
I can't change the parent of Der1 and Der2! It should be Base.
Since you can't change the inheritance structure, make a helper class that contains the common code and include it by composition rather than inheritance.
# Common code goes in this new class
class DerHelper:
def __init__(self, parent):
self._parent = parent
def OwnFoo(self):
print 'Do something 1', self._parent
def OwnFoo2(self):
print 'Do something 2', self._parent
def Foo(self):
print 'Do something 3', self._parent
# First derived class
class Der1(Base):
def __init__(self):
# include helper class by composition
self._helper = DerHelper('Der1')
def OwnFoo(self):
self._helper.OwnFoo()
def OwnFoo2(self):
self._helper.OwnFoo2()
def Foo(self):
self._helper.Foo()
# Second derived class
class Der2(Base):
def __init__(self):
# include helper class by composition
self._helper = DerHelper('Der2')
def OwnFoo(self):
self._helper.OwnFoo()
def OwnFoo2(self):
self._helper.OwnFoo2()
def Foo(self):
self._helper.Foo()
Of course, you could pass a reference to the parent instead of a string. I just did it this way for demonstration purposes.
Usage:
d = Der1()
d.OwnFoo()
d.OwnFoo2()
d.Foo()
d = Der2()
d.OwnFoo()
d.OwnFoo2()
d.Foo()
Output:
Do something 1 Der1
Do something 2 Der1
Do something 3 Der1
Do something 1 Der2
Do something 2 Der2
Do something 3 Der2
Make Der2 a subclass of Der1 and you're done.
class Base:
def Foo(self):
pass
# First derived class
class Der1(Base):
def OwnFoo(self):
# Do something 1
def OwnFoo2(self):
# Do something 2
def Foo(self):
# Do something 3
# Second derived class (subclasses Der1)
class Der2(Der1):
pass
Any behavior within Der2 you'd like to specialize can added within the class definition. If you create a new method of the same name in Der2 (e.g. Der2.OwnFoo()), then it will overload the default method that is inherited from Der1.
EDIT: If you can't change the parent, put all of the behavior you want to inherit in the base class keeping in mind that you can overload or customize any of the methods in the subclasses.
In code:
# Base class
class Base:
def Foo1(self):
# Do something 1
def Foo2(self):
# Do something 2
def Foo(self):
# Do something 3
# First derived class, inherits everything from Base
class Der1(Base):
pass
# Second derived class
class Der2(Base):
pass
There is a "trick" you can do to call the original method inherited from the parent, capture the return value and then customize the behavior. This will only work if the method actually returns a value, and can be dangerous if the method manipulates attributes within the class, unless that's what you want and expect it.
In code:
# Second derived class, with customized methods
class Der2(Base):
# Anything that is not explicitly define is inherited from parent
# as-is.
def Foo(self):
# My Foo() overloads Base.Foo() inherited from parent class.
# Do something "special" 3
def Foo1(self):
# Calls parent Base.Foo1() and then manipulates return data.
base_output = Base.Foo1(self)
# Do something "special" 1 with 'base_output'
Is this a homework?
Look at the first line of Der2:
class Der2(Base):
What says what is its parent (e.g. a class it descends and herits methods and attributes from)? How could you change this?
If Der1 and Der2 share a lot of code, then you should put that in a superclass; since Base cannot be touched, introduce a class in between:
class Der(Base):
def OwnFoo(self):
...
class Der1(Der):
...
class Der2(Der):
...
(Depending on you class hierachy, the "derive Der2 from Der1" option that others recommend may also be valid.)
How about making Der2 subclass Der1?

Categories