how should i access a class variable from another class in python? - python

I have checked lots of websites and almost all questions related to the same on Stackoverflow. I cant find the solution to this problem. Its very important for a project. Please help. I want to use the variable self.email in Class A in the function email(self) in Class B. I've tried several things, but its not working. Inheritance wont work because its a kivy-python code and its already inheriting classes like GridLayout().
Class A:
def __init__(self):
---some code---
def email_id(self):
self.email = x
Class B:
def __init__(self):
print(A().email)

I think what you might be looking for are property decorators
Class A:
def __init__(self):
---some code---
#property
def email(self):
return (some code to show the email)

The field email of class A is created when email_id() is called.
Therefore, by the time print(A().email) is executed, this field is still not set.
You can set it first
Class B:
def __init__(self):
a = A()
a.email_id("email")
print(a.email)

Related

How do I know which method will be called in Python 3?

I have these classes in my exercises:
class A:
def accept(self,v):
v.visitA(self)
class B(A):
def accept(self,v):
v.visitB(self)
class C:
def accept(self,v):
v.visitC(self)
class Visitor:
def visitA(self,x):
return x.accept(self)
def visitB(self,x):
pass
def visitC(self,x):
pass
And my question is that x.accept(self) in method visitA of class Visitor can call (indirectly) which method of class Visitor?
I am not really understand these code despite reading about python inheritance. Is there anybody can help me to explain this code?
Thank you in advance!

Use outer class instance as self in inner class?

I'm writing a wrapper for the GMAIL API. In this wrapper, I am trying to include subattributes in the "main class" so it more closely follows the below:
Previously, I was use methods such as:
class Foo:
def __init__(self, ...):
# add some attributes
def get_method(self, ...):
return some_stuff
This allows me to do foo.get_method(...). To follow the GMAIL API, I try to do:
class Foo:
def __init__(self, ...):
# add some attributes
#property
def method(self):
class _Method:
#staticmethod
def get(self, ...):
return some_stuff
return _Method()
Which allows me to do foo.method.get(...). The above has some problems, it redefines the class every time, and I have to add #staticmethod above every method as part of it. I do realise that I could create the class at the outer class level, and set a hidden variable for each which then .method returns or creates, but this seems like too much workaround.
tldr: Is it possible to make the instance passed to the inner class as self be the instance of the outer class (I do not wish to have to pass the attributes of the outer class to each inner class).
Instead of sharing the self parameter between classes, you are probably better off just passing the things you need to the constructor of the class you instantiate.
class Messages:
def __init__(self, name):
self.name = name
def method(self, other_arg):
return self.name + other_arg
class Test:
name = "hi"
def __init__(self):
self.messages = Messages(name=self.name)
If you need to pass a lot of information to the constructor and it starts becoming unwieldy, you can do something like split the shared code into a third class, and then pass that between the Test and Messages classes as a single object.
In Python there are all sorts of clever things that you can do with metaclasses and magic methods, but in 99% of cases just refactoring things into different classes and functions will get you more readable and maintainable code.
Users should have an instance of messages, which allows method get. The scetch for code is:
class Messages:
...
def get()
...
class Users:
...
messages = Messages(...)
allows
users = Users()
users.messages.get()
The bad thing in this API is plural names, which is a bad sign for class. If done from scratch you would rather have classes User and Message, which make more sense.
If you have a closer look at GET/POST calls in the API you link provided, you would notice the urls are like UserId/settings, another hint to implement User class, not Users.
self in the methods reference the self of the outer class
maybe this is what you want factory-method
Although the example code I'll provide bellow might be similar to the already provided answers, and the link above to another answer might satify you wish, because it is slight different formed I'll still provide my vision on what you asked. The code is self explanatory.
class User:
def __init__(self, pk, name):
self.pk = pk
self.name = name
self._messages = None
def messages(self):
if self.messages is None:
self._messages = Messages(self.pk)
return self._messages
class Messages:
def __init__(self, usr):
self.usr = usr
def get(self):
return self._grab_data()
def _grab_data(self):
# grab the data from DB
if self.usr == 1:
print('All messages of usr 1')
elif self.usr == 2:
print('All messages of usr 2')
elif self.usr == 3:
print('All messages of usr 3')
one = User(1, 'One')
two = User(2, 'Two')
three = User(3, 'Three')
one.messages().get()
two.messages().get()
three.messages().get()
The messages method approach practical would be the same for labels, history etc.
Edit: I'll give one more try to myself trying to understand what you want to achieve, even though you said that
I have tried numerous things with defining the classes outside of the container class [...]
. I don't know if you tried inheritance, since your inner class me, despite it quite don't represent nothing here, but still looks like you want to make use of its functionality somehow. You said as well
self in the methods reference the self of the outer class
This sounds to me like you want inheritance at the end.
Then the way to go would be (a proximity idea by using inheritance):
class me(object):
def __init__(self):
self.__other_arg = None # private and hidden variable
# setter and getter methods
def set_other_arg(self, new_other_arg):
self.__other_arg = new_other_arg
def get_other_arg(self):
return self.__other_arg
class Test(me):
name = 'Class Test'
#property
def message(self):
other_arg = self.get_other_arg()
if other_arg is not None:
return '{} {}'.format(self.name, other_arg)
else:
return self.name
t = Test()
t.set_other_arg('said Hello')
print(t.message)
# output >>> Class Test said Hello
I think this could be a preferable way to go rather than your inner class approach, my opinion, you'll decide. Just one side note, look up for getter and setter in python, it might help you if you want to stick with the inheritance idea given.

Python application architecture

I'm trying to create task management system. (an app where somebody can create a task and set up a deadline date and get notifications). At first i will create console app and then web using django.
I already created a database.(sqlite)
I don't know how my entities are going to communicate.
First one approach:
class User():
def __init__(self):
self.UserID
self.UserName
self.PassHash
# salt, Full name and etc.
class Task():
def __init__(self):
self.TaskID
self.UserID
self.Name
#smth subtasks, date and etc.
class UserService():
def __init__(UserID, TaskID):
User = db.GetById(UserID)
TasksList = db.GetUserTasks(UserID)
def addTask():
..
def removeTask():
..
def ChangePassword():
..
def ChangeUserName():
..
The last one class will contains all business logic and communication between Tasks and User classes. First ones - pure classes without any methods.
Another one approach:
class User():
def __init__(self):
self.UserID #
self.UserName
self.PassHash # 3 fields will be set up by db. The last one - on #runtime
self.TasksList = None
def ChangePassword():
..
def GetTasks():
TaskList = db.GetUserTasks(UserID)
class Task()
def __init__(self):
self.TaskID
self.UserID
self.Name
self.SubTask
#smth else
def AddSubTask():
..
Thanks in advance
Classes should define objects of which you can have one or more instances of. That is for example users or tasks. I do not think that classes in object programming are supposed to encompass raw functionality, for that you just use functions...
With that in mind I would go with the first approach.
Classes should be classes and functions should be functions - Me
I'd go with the first option because it's more readable and the structure is clearer.

How does this python inheritance hierarchy work? (specific example)

I am working on a code base that uses oop and I am relavtively new to it. My question specifically is, why NewMenuItem not inherit from File?
code bunk to play with code: https://codebunk.com/b/350127244/
"""Build class hierarchy and get values from decendants"""
import inspect
def selftest():
class Menu(object):
def __init__(self):
super(Menu, self).__init__()
self.value = "Menu"
class MenuBar(Menu):
#having object in there makes it a new style object, which allows us to use super
def __init__(self):
super(MenuBar, self).__init__()
self.value = "MenuBar"
class File(MenuBar):
def __init__(self):
Menu.__init__()
super(File, self).__init__()
self.value = "File"
self.FileValue = "File here!"
class New(Menu):
def __init__(self):
Menu.__init__()
pass
class NewMenuItem(Menu):
def __init__(self):
"""
Q 1- Why do I need self here?
Menu.__init__(self)
"""
Menu.__init__(self)
pass
def show_vals(self):
print(self.value)
"""
Q 2 -why wont this work?
def show_vals2(self):
print(self.FileValue)
"""
example = File.New.NewMenuItem()
example.show_vals()
"""
Q 3 - Why do I get this error with this line?
inspect.getmro(example)
AttributeError: 'ManageProduct' object has no attribute '__bases__'
"""
I'm trying to understand what is happening line by line, but what I don't get is why NewMenuItem doesn't inherit from File.
I tried hard-coding the instantiation of File,like so:
File.init()
but then I get an error unless I pass the File object:
File.__init__(File())
I guess what I am struggling with is:
-inheritance trees
-super classes
-why we need to hard-code instantiations in this case
Keep in mind that this is the code I have come across. I am not sure why this is the way it is.
Inheritance and scope are two completely different things. NewMenuItem is defined inside the scope of the class New, inside of the scope of the class File, but it inherits from Menu, which inherits from object. So while NewMenuItem will only be accessible through the class File and again through New, it will inherit its methods from Menu, and super will refer to Menu.

Inheritance in python 2.7

I am attempting to build a framework for parsing a very specific text structure.
The structure that I am processing is rich and has a known schema, similar to xml.
I am attempting to build an framework to do the parsing. The text has various sections and I anticipate that more sections code be added in the future. To Compensate, I am attempting to build a series of derived classed that can be swapped in or out as needed.
I thought everything was going as planned, until I started coding up the first derived class.
The base class has some functionality inside of __init__ that I was expecting that I would get for free in all of the concrete derived classes. That however, doesn't seem to be the case at all.
Here is a simple example to illustrate my problem:
I would expect the output to be:
['memberA', 'memberB', 'memberC'],
['DerivedA', 'DerivedB', 'DerivedC']
class base(object):
def __init__(self):
members = [attr for attr in dir(self) if not callable(attr) and not attr.startswith("__")]
print members
class test(base):
def __init__(self):
self.memberA = None
self.memberB = None
self.memberC = None
class test2(test):
def __init__(self):
self.DerivedA = None
self.DerivedB = None
self.DerivedC = None
t = test()
t2 = test2()
Can someone please explain to my, why the print functionality is not working as I expect it?
EDIT:
in light of the answer below: I now have this question:
What if base.__init(self) instead looked like:
class base(object):
def __init__(self, text):
would I have to define the derived class as:
class test(base):
def __init__(self, text):
base.__init__(self, text)
I was hoping to at least get the parameter object referance for free
In Python, you must call the base class's __init__ explicitly inside test.__init__:
class test(base):
def __init__(self):
base.__init__(self)
Or, if you wish to support multiple inheritance, use super:
class test(base):
def __init__(self):
super(test, self).__init__()
If the base.__init__ looks like
class base(object):
def __init__(self, text):
then test.__init__ should indeed look like
class test(base):
def __init__(self, text):
base.__init__(self, text)
See Guido van Rossum's blog for why self is explicit in Python.
PS. PEP8 recommends using CapWords for class names.
you are overwriting init in test2
following code will complete overwrite init in test. so there is no longer a print int the init function.
def __init__(self):
self.DerivedA = None
self.DerivedB = None
self.DerivedC = None

Categories