Having trouble understanding the problem in my code, new to classes (generally python too, so sorry if I name things wrong). I receive this error:
I think my code is too long winded to include in here, so I made a simplified version to test the concept below.
The question is, how can I create a new self object "self4"? Which would then be available to other functions within the class. Currently I get this error.
AttributeError: 'className' object has no attribute 'self4'
class className(object):
def __init__(self, self1=1,self2=2,self3=3):
self.self1=self1
self.self2=self2
self.self3=self3
def evaluate(self, self5):
print className.func1(self) + className.func2(self)
self.self5=self5
print className.func1(self)
def func1(self):
return self.self1 + self.self5
def func2(self):
self.self4 = self.self1+self.self2+self.self3
return self.self4
filename tester.py
import tester.py
mst=tester.className()
mst.evaluate()
Edit:
Your code works fine!
What is the Problem?
I still think it is better to move self4 into the init!
Original
I think the most logical thing would be to define self4 on init:
class className(object):
def __init__(self, self1=1, self2=2, self3=3):
self.self1 = self1
self.self2 = self2
self.self3 = self3
self.self4 = None
#rest of class
If anyone still has this issue: you get this error when your indentation is goofed.To fix the asked question above, you just have to add a space before the last two functions definitions, that is;
class className(object):
def __init__(self, self1=1,self2=2,self3=3):
self.self1=self1
self.self2=self2
self.self3=self3
def evaluate(self, self5):
print className.func1(self) + className.func2(self)
self.self5=self5
print className.func1(self)
def func1(self):
return self.self1 + self.self5
def func2(self):
self.self4 = self.self1+self.self2+self.self3
return self.self4
just make sure they all have similar indentation, and you are good to go.
You should pass self4 in method.
Related
Hello so im new to python and im in progress to learning class and function. I keep getting this error code, i don't know whats wrong on my code. Here is the source code:
class Data:
def __init__(self,nama):
self.nama=nama
def __private(self):
self.ganti="Replace"
def ganti(self):
self.prvt=self.ganti
print(self.prvt)
class User(Data):
def __init__(self,nama):
self.nama=nama
super().__init__
def printUsername(nama):
print(nama)
user1 = User("Test")
user1.printUsername()
user1.ganti()
user1.printUsername()
When i run, the output is like this:
<__main__.User object at 0x000002C1B781D310>
<bound method Data.ganti of <__main__.User object at 0x000002C1B781D310>>
<__main__.User object at 0x000002C1B781D310>
Press any key to continue . . .
So whats wrong on my code? I excpeted the output is:
Test
Replace
You have some Syntax error in your code.
Variable name and function name shouldn't be the same.
When a variable is defined in init, all functions use it and there is no need to redefine it. Even when a class inherits from another class.
This code will print the output you want.
class Data:
def __init__(self, nama):
self.nama = nama
self.ganti = "Replace"
self.prvt = self.ganti
def Ganti(self):
print(self.prvt)
def __private(self):
pass
class User(Data):
"""
def __init__(self):
super().__init__()
# because we don't have new variable to define, we can remove this function.
"""
def printUsername(self):
print(self.nama)
User('Test').printUsername()
User('Test').Ganti()
I'm not sure whether this is a great approach to be using, but I'm not hugely experienced with Python so please accept my apologies. I've tried to do some research on this but other related questions have been given alternative problem-specific solutions - none of which apply to my specific case.
I have a class that handles the training/querying of my specific machine learning model. This algorithm is running on a remote sensor, various values are fed into the object which returns None if the algorithm isn't trained. Once trained, it returns either True or False depending on the classification assigned to new inputs. Occasionally, the class updates a couple of threshold parameters and I need to know when this occurs.
I am using sockets to pass messages from the remote sensor to my main server. I didn't want to complicate the ML algorithm class by filling it up with message passing code and so instead I've been handling this in a Main class that imports the "algorithm" class. I want the Main class to be able to determine when the threshold parameters are updated and report this back to the server.
class MyAlgorithmClass:
def feed_value(self):
....
class Main:
def __init__(self):
self._algorithm_data = MyAlgorithmClass()
self._sensor_data_queue = Queue()
def process_data(self):
while True:
sensor_value = self._sensor_data_queue.get()
result, value = self._algorithm_data.feed_value(sensor_value)
if result is None:
# value represents % training complete
self._socket.emit('training', value)
elif result is True:
# value represents % chance that input is categoryA
self._socket.emit('categoryA', value)
elif result is False:
...
My initial idea was to add a property to MyAlgorithmClass with a setter. I could then decorate this in my Main class so that every time the setter is called, I can use the value... for example:
class MyAlgorithmClass:
#property
def param1(self):
return self._param1
#param1.setter
def param1(self, value):
self._param1 = value
class Main:
def __init__(self):
self._algorithm_data = MyAlgorithmClass()
self._sensor_data_queue = Queue()
def watch_param1(func):
def inner(*args):
self._socket.emit('param1_updated', *args)
func(*args)
My problem now, is how do I decorate the self._algorithm_data.param1 setter with watch_param1? If I simply set self._algorithm_data.param1 = watch_param1 then I will just end up setting self._algorithm_data._param1 equal to my function which isn't what I want to do.
I could use getter/setter methods instead of a property, but this isn't very pythonic and as multiple people are modifying this code, I don't want the methods to be replaced/changed for properties by somebody else later on.
What is the best approach here? This is a small example but I will have slightly more complex examples of this later on and I don't want something that will cause overcomplication of the algorithm class. Obviously, another option is the Observer pattern but I'm not sure how appropriate it is here where I only have a single variable to monitor in some cases.
I'm really struggling to get a good solution put together so any advice would be much appreciated.
Thanks in advance,
Tom
Use descriptors. They let you customize attribute lookup, storage, and deletion in Python.
A simplified toy version of your code with descriptors looks something like:
class WatchedParam:
def __init__(self, name):
self.name = name
def __get__(self, instance, insttype=None):
print(f"{self.name} : value accessed")
return getattr(instance, '_' + self.name)
def __set__(self, instance, new_val):
print(f"{self.name} : value set")
setattr(instance, '_' + self.name, new_val)
class MyAlgorithmClass:
param1 = WatchedParam("param1")
param2 = WatchedParam("param2")
def __init__(self, param1, param2, param3):
self.param1 = param1
self.param2 = param2
self.param3 = param3
class Main:
def __init__(self):
self._data = MyAlgorithmClass(10, 20, 50)
m = Main()
m._data.param1 # calls WatchedParam.__get__
m._data.param2 = 100 # calls WatchedParam.__set__
The WatchedParam class is a descriptor and can be used in MyAlgorithmClass to specify the parameters that need to be monitored.
The solution I went for is as follows, using a 'Proxy' subclass which overrides the properties. Eventually, once I have a better understanding of the watched parameters, I won't need to watch them anymore. At this point I will be able to swap out the Proxy for the base class and continue using the code as normal.
class MyAlgorithmClassProxy(MyAlgorithmClass):
#property
def watch_param1(self):
return MyAlgorithmClass.watch_param1.fget(self)
#watch_param1.setter
def watch_param1(self, value):
self._socket.emit('param1_updated', *args)
MyAlgorithmClass.watch_param1.fset(self, value)
In a module, I would like to ask an instance of a class to update a class attribute if needed. Here's an example of the code:
class ExampleClass:
def __init__(self):
self.data1 = None
self.data2 = None
self.data3 = None
def updateData1(self, withInfo):
self.dataUpdater(self.data1, withInfo)
def updateData2(self, withInfo):
self.dataUpdater(self.data2, withInfo)
def updateData3(self, withInfo):
self.dataUpdater(self.data3, withInfo)
def dataUpdater(self, data, withInfo):
# Very long and complex class function.
# I would like to keep this logic in one function instead of making copies of it.
data = 'new data'
But when that data is updated and I try to get that particular data in another module it's still None. Now I understand what is going on. I am basically rewriting and making a new variable in the dataUpdater called data. And my particular class attribute is never being updated. My question is how can I update the data (the particular class attribute) that I passed in?
I have spent half the day trying to figure this out and I can not seem to find anything like what I am trying.
You could try setting the attribute you want to update with setattr. ie
class ExampleClass:
def __init__(self):
self.data1 = None
self.data2 = None
self.data3 = None
def updateData1(self, withInfo):
self.dataUpdater('data1', withInfo)
def updateData2(self, withInfo):
self.dataUpdater('data2', withInfo)
def updateData3(self, withInfo):
self.dataUpdater('data3', withInfo)
def dataUpdater(self, attr_name, withInfo):
# Very long and complex class function.
# I would like to keep this logic in one function instead of making copies of it.
setattr(self, attr_name, 'new_data')
You are attempting to pass the self.data# variables by reference, which is not something you can control easily in Python as in languages like C. If you would like to keep a similar implementation, consider using an array for your object, and passing an index for the value to update to the dataUpdater method.
I have the following class:
class state(list):
def __init__(self,parent = None, path = None, *args):
list.__init__(self, *args)
self.n = len(self)
self.parent = parent
self.path = path
def neighbors(self):
lista = []
if self.__hasUp():
lista.append(state(Self,'Up',self.__swap(self.index(0),self.index(0) - 3))))
if self.__hasDown():
lista.append(state(Self,'Down',self.__swap(self.index(0),self.index(0) + 3))))
if self.__hasLeft():
lista.append(state(Self,'Left',self.__swap(self.index(0),self.index(0) - 1))))
if self.__hasRight():
lista.append(state(Self,'Right',self.__swap(self.index(0),self.index(0) + 1))))
return lista
I normally create an instance of the class as follow:
inicial = state(None,None,[1,2,5,3,4,0,6,7,8])
I need to do the followin (I think if I put the whole context of what I am doing, it will be missleading):
anotherList = []
for neighbor in inicial.neighbors():
anotherList.append(neighbor)
I just want to have a list with few extra attributes and methods. The problem is I need this class to create istances of itself with the object that is creating them as a parameter in the neighbors method. I have testet all methods referenced in the code and they work as expected, but I just think they are not need for this question and they will make it a really long question.
I have also checked this Declaring a class with an instance of it inside in Python, Create static instances of a class inside said class in Python and this Class constructor able to init with an instance of the same class object. However, I do not understand it yet :(
I am quite an amateur,so if you have any suggestions, they are all welcome ;)
I am sorry..I tried and it turns out it is very straightforward. It was simply a mistake from the beggining. I leave the answer here in case someone needs it, but if you suggest I delete it (is it possible?) I'will do it.
class test(list):
def __init__(self,pa, name, *args):
list.__init__(self, *args)
self.name = name
self.par = pa
def create(self):
lista = []
lista.append(test(self,'a',[0,1]))
lista.append(test(self,'b',[0,2]))
return lista
Best regards,
OK, in C# we have something like:
public static string Destroy(this string s) {
return "";
}
So basically, when you have a string you can do:
str = "This is my string to be destroyed";
newstr = str.Destroy()
# instead of
newstr = Destroy(str)
Now this is cool because in my opinion it's more readable. Does Python have something similar? I mean instead of writing like this:
x = SomeClass()
div = x.getMyDiv()
span = x.FirstChild(x.FirstChild(div)) # so instead of this
I'd like to write:
span = div.FirstChild().FirstChild() # which is more readable to me
Any suggestion?
You can just modify the class directly, sometimes known as monkey patching.
def MyMethod(self):
return self + self
MyClass.MyMethod = MyMethod
del(MyMethod)#clean up namespace
I'm not 100% sure you can do this on a special class like str, but it's fine for your user-defined classes.
Update
You confirm in a comment my suspicion that this is not possible for a builtin like str. In which case I believe there is no analogue to C# extension methods for such classes.
Finally, the convenience of these methods, in both C# and Python, comes with an associated risk. Using these techniques can make code more complex to understand and maintain.
You can do what you have asked like the following:
def extension_method(self):
#do stuff
class.extension_method = extension_method
I would use the Adapter pattern here. So, let's say we have a Person class and in one specific place we would like to add some health-related methods.
from dataclasses import dataclass
#dataclass
class Person:
name: str
height: float # in meters
mass: float # in kg
class PersonMedicalAdapter:
person: Person
def __init__(self, person: Person):
self.person = person
def __getattr__(self, item):
return getattr(self.person, item)
def get_body_mass_index(self) -> float:
return self.person.mass / self.person.height ** 2
if __name__ == '__main__':
person = Person('John', height=1.7, mass=76)
person_adapter = PersonMedicalAdapter(person)
print(person_adapter.name) # Call to Person object field
print(person_adapter.get_body_mass_index()) # Call to wrapper object method
I consider it to be an easy-to-read, yet flexible and pythonic solution.
You can change the built-in classes by monkey-patching with the help of forbidden fruit
But installing forbidden fruit requires a C compiler and unrestricted environment so it probably will not work or needs hard effort to run on Google App Engine, Heroku, etc.
I changed the behaviour of unicode class in Python 2.7 for a Turkish i,I uppercase/lowercase problem by this library.
# -*- coding: utf8 -*-
# Redesigned by #guneysus
import __builtin__
from forbiddenfruit import curse
lcase_table = tuple(u'abcçdefgğhıijklmnoöprsştuüvyz')
ucase_table = tuple(u'ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ')
def upper(data):
data = data.replace('i',u'İ')
data = data.replace(u'ı',u'I')
result = ''
for char in data:
try:
char_index = lcase_table.index(char)
ucase_char = ucase_table[char_index]
except:
ucase_char = char
result += ucase_char
return result
curse(__builtin__.unicode, 'upper', upper)
class unicode_tr(unicode):
"""For Backward compatibility"""
def __init__(self, arg):
super(unicode_tr, self).__init__(*args, **kwargs)
if __name__ == '__main__':
print u'istanbul'.upper()
You can achieve this nicely with the following context manager that adds the method to the class or object inside the context block and removes it afterwards:
class extension_method:
def __init__(self, obj, method):
method_name = method.__name__
setattr(obj, method_name, method)
self.obj = obj
self.method_name = method_name
def __enter__(self):
return self.obj
def __exit__(self, type, value, traceback):
# remove this if you want to keep the extension method after context exit
delattr(self.obj, self.method_name)
Usage is as follows:
class C:
pass
def get_class_name(self):
return self.__class__.__name__
with extension_method(C, get_class_name):
assert hasattr(C, 'get_class_name') # the method is added to C
c = C()
print(c.get_class_name()) # prints 'C'
assert not hasattr(C, 'get_class_name') # the method is gone from C
I'd like to think that extension methods in C# are pretty much the same as normal method call where you pass the instance then arguments and stuff.
instance.method(*args, **kwargs)
method(instance, *args, **kwargs) # pretty much the same as above, I don't see much benefit of it getting implemented in python.
After a week, I have a solution that is closest to what I was seeking for. The solution consists of using getattr and __getattr__. Here is an example for those who are interested.
class myClass:
def __init__(self): pass
def __getattr__(self, attr):
try:
methodToCall = getattr(myClass, attr)
return methodToCall(myClass(), self)
except:
pass
def firstChild(self, node):
# bla bla bla
def lastChild(self, node):
# bla bla bla
x = myClass()
div = x.getMYDiv()
y = div.firstChild.lastChild
I haven't test this example, I just gave it to give an idea for who might be interested. Hope that helps.
C# implemented extension methods because it lacks first class functions, Python has them and it is the preferred method for "wrapping" common functionality across disparate classes in Python.
There are good reasons to believe Python will never have extension methods, simply look at the available built-ins:
len(o) calls o.__len__
iter(o) calls o.__iter__
next(o) calls o.next
format(o, s) calls o.__format__(s)
Basically, Python likes functions.