I try to test my program to create a copy of an object and I get this error:
TypeError: __init__() takes 1 positional argument but 2 were given
I tried to check existing questions but I can't correct this error. Any suggestions?
This is my class:
class ordred_dict:
#"""
#This class is an ordred dictionary
#composed of 2 listes: key list and value list as a dictionary
#"""
def __init__(self, orig):
#"""
#Constructur to initiate an empty key and value list
#"""
self.key_list=list(orig.key_list)
self.value_list=list(orig.value_list)
def __init__(self, **Tuplekeysvalues):
#"""
#Create a new dict using a liste of (keys:values)
#"""
self.key_list=list()
self.value_list=list()
for key in Tuplekeysvalues:
self.key_list.append(key)
self.value_list.append(Tuplekeysvalues[key])
#print("({}:{}) ".format(key, Tuplekeysvalues[key]))
#Main program
dict3=ordred_dict(p1="1",p2="2",p4="4",p3="3",p0="0")
dict2=ordred_dict(dict3)
You can't overload constructors in Python like you can in some other languages. A better way of doing this would be something like:
class MyOrderedDict:
def __init__(self, *args):
self.key_list = []
self.value_list = []
for key,val in args:
self.key_list.append(key)
self.value_list.append(val)
#classmethod
def from_ordered_dict(cls, other):
return cls(*zip(other.key_list, other.value_list))
Then call it with:
d = MyOrderedDict(('key1', 'value1'), ('key2', 'value2'))
e = MyOrderedDict.from_ordered_dict(d)
Related
I want a class with static attributes that can be stored using one or more get methods from outside and the stored values can be retrieved using one or more get methods
class contract_data:
contract_header = dict()
contract_item = dict()
contract_schedule = dict()
# #staticmethod
def put_header(line:list,findex:dict):
contract_header[line[findex['VBELN_VA']]] = {'KNKLI':[line[findex['KNKLI']]],
'VTWEG':[line[findex['VTWEG']]],
'SPART':[line[findex['SPART']]],
'VKBUR':[line[findex['VKBUR']]],
'VKGRP':[line[findex['VKGRP']]],
'BSTKD':[line[findex['BSTKD']]]
}
def get_header(keyval:str)->dict:
return contract_header[keyval]
# #staticmethod
def put_item(line: list, findex: dict):
return
#staticmethod
def put_schedule(line: list, findex: dict):
return
I expected that calling contract_data.put_header(line,findex) I could store values in contract_data attribute contract_header. But it fails with runtime error
in put_header:
contract_header[line[findex['VBELN_VA']]] = {'KNKLI':[line[findex['KNKLI']]],
NameError: name 'contract_header' is not defined. Did you mean: 'contract_data'?
I played around with #staticmethod and .self or self. with no success.
I expect the class attributes, the dictionaries can be used within the class but not outside.
Your dicts are not global variables; they're class attributes, and as such need to be accessed from the class. That means your static methods need to be defined as class methods.
class contract_data:
contract_header = dict()
contract_item = dict()
contract_schedule = dict()
#classmethod
def put_header(cls, line: list, findex: dict):
cls.contract_header[line[findex['VBELN_VA']]] = {
k: [line[findex[k]]]
for k in ['KNKLI', 'VTWEB', 'SPART', 'VKBUR', 'VKGRP', 'BSTKD']}
#classmethod
def get_header(cls, keyval: str)->dict:
return cls.contract_header[keyval]
...
I have a project with a class "ListObject" containing a list and a string attribute "_quality" explaining the list content. The string attribute is calculated through a private method of the class called "_update_quality(self)". The list is populated with instances of an object "Element": it has an int attribute "_value" that can be changed through the public method "add(self, value)" that takes an int value and adds it to _value.
ListObject has a public method "change_item(self, index, value)" that let the user add an int value to the Element instance at the given index.
You can read and run the code below to see how it works.
class Element:
def __init__(self):
self._value = 0
def add(self, value):
self._value += value
def __str__(self):
return str(self._value)
class ListObject:
def __init__(self):
self._list = list()
self._quality = str()
self._list.append(Element())
self._list.append(Element())
self._list.append(Element())
self._update_quality()
def __getitem__(self, item):
return self._list[item]
def _update_quality(self):
self._quality = str()
for item in self._list:
self._quality += str(item)
def change_item(self, index, value):
self._list[index].add(value)
self._update_quality()
#property
def quality(self):
return self._quality
o = ListObject()
print(o.quality)
o.change_item(0, 5)
print(o.quality)
What I'd like to implement is a getitem method inside ListObject that works like "change_item". The method should automatically call "_update_quality". This should be the code:
o = ListObject()
print(o.quality)
o[0].add(5)
print(o.quality)
and it should generate the same output as the previous one.
Does anyone knows how I can achieve this?
I was clear how dictionaries work in Python until I found this logic.
class Sample:
__test = {}
def __init__(self):
self.__dict__ = self.__test
self.key = "answer"
self.count = "numbers"
def print_test(self):
print(self.__test)
s = Sample()
s.print_test()
In the above code a dictionary is initialized and then same variable is assigned to the class dict. In the next line we are initializing 2 more variables to the class.
In the end we are initializing Sample class to an "s object"
As per my understanding this should be following output and __test dictionary should be empty
s.count = "numbers"
s.key = "answers"
But to my surprise the print_test functions returns
{'count': 'numbers', 'key': 'answer'}
Can anyone explain how the __test dictionary got these items as key value pairs.
The __init__ function runs sequentially. When you set self.__dict__ = self.__test, you assign the object's internal state dictionary to be empty. However, when you next set the values of self.key and self.count, those attributes are added to the now empty self.__dict__, and by mutual assignment, to self.__test
You can see the difference you assign the empty dict at the end of the __init__ method.
class Sample:
__test = {}
def __init__(self):
self.key = "answer"
self.count = "numbers"
self.__dict__ = self.__test
def print_test(self):
print(self.__test)
s = Sample()
s.print_test()
# prints:
{}
I have a simple python class that consists of some attributes and some methods.What i need is to make a list out of the class attributes ( only ! )
Class A():
def __init__(self, a=50, b="ship"):
a = a
b = b
def method1():
.....
I want to have a list :
[50, "ship"]
Another solution, possibly more generic, is:
def asList(self):
[value for value in self.__dict__.values()]
Full example with correct syntax:
class A:
def __init__(self, a=50, b="ship"):
self.a = a
self.b = b
def as_list(self):
return [value for value in self.__dict__.values()]
a = A()
print a.as_list()
output:
[50, 'ship']
def asList(self):
return [a,b,....] # will create a new list on each call
Unless you also create an __init__(...) or factory methods or something alike for your class that decomposes this list you wont be able to create a new object back from the list.
See how-to-overload-init-method-based-on-argument-type
I am using a technique discussed here before, to turn a dictionary into an object, so that I can access the elements of the dictionary with the dot (.) notion, as instance variables.
This is what I am doing:
# Initial dictionary
myData = {'apple':'1', 'banana':'2', 'house':'3', 'car':'4', 'hippopotamus':'5'}
# Create the container class
class Struct:
def __init__(self, **entries):
self.__dict__.update(entries)
# Finally create the instance and bind the dictionary to it
k = Struct(**myData)
So now, I can do:
print k.apple
and the result is:
1
This works, however the issues start if I try to add some other methods to the "Struct" class. For example lets say that I am adding a simple method that just creates an variable:
class Struct:
def __init__(self, **entries):
self.__dict__.update(entries)
def testMe(self):
self.myVariable = 67
If I do:
k.testMe()
My dictionary object is broken, "myVariable" is inserted as a key with the value "67". So If I do:
print k.__dict__
I am getting:
{'apple': '1', 'house': '3', 'myVariable': 67, 'car': '4', 'banana': '2', 'hippopotamus': '5'}
Is there a way to fix this? I kind of understand what is happening, but not sure If I need to entirely change my approach and build a class with internal methods to handle the dictionary object or is there a simpler way to fix this problem?
Here is the original link:
Convert Python dict to object?
Thanks.
For your needs, don't store you variables in __dict__. Use your own dictionary instead, and override .__getattr__ (for print k.apple) and __setattr__ (for k.apple=2):
# Initial dictionary
myData = {'apple':'1', 'banana':'2', 'house':'3', 'car':'4', 'hippopotamus':'5'}
# Create the container class
class Struct:
_dict = {}
def __init__(self, **entries):
self._dict = entries
def __getattr__(self, name):
try:
return self._dict[name]
except KeyError:
raise AttributeError(
"'{}' object has no attribute or key '{}'".format(
self.__class__.__name__, name))
def __setattr__(self, name, value):
if name in self._dict:
self._dict[name] = value
else:
self.__dict__[name] = value
def testMe(self):
self.myVariable = 67
def FormattedDump(self):
return str(self._dict)
# Finally create the instance and bind the dictionary to it
k = Struct(**myData)
print k.apple
print k.FormattedDump()
k.testMe()
k.apple = '2'
print k.FormattedDump()
In the alternative, if your FormattedDump() routine is bothering you, you could just fix it:
# Initial dictionary
myData = {'apple':'1', 'banana':'2', 'house':'3', 'car':'4', 'hippopotamus':'5'}
# Create the container class
class Struct:
def __init__(self, **entries):
self.__dict__.update(entries)
self.public_names = entries.keys()
def testMe(self):
self.myVariable = 67
def GetPublicDict(self):
return {key:getattr(self, key) for key in self.public_names}
def FormattedDump(self):
return str(self.GetPublicDict())
# Finally create the instance and bind the dictionary to it
k = Struct(**myData)
print k.apple
print k.FormattedDump()
k.testMe()
k.apple = '2'
print k.FormattedDump()