Class template with methods already defined - python-3.x

I have two methods inside a class (mask_im and save_im) that I must include in several other classes in separate modules. How can I create a class with those two methods without copying and paste 10 lines of code, or at least reduce it to two lines of code? I want to have like a class template or something that I can reuse easily.
class MaskFromImages:
def __init__(self, im_to_mask, m_rules, val_assign=None):
im_mem = ReadMap(im_to_mask, mem=True)
self.reference = im_mem.reference
if im_mem.no_data is None:
self.out_no_data = 255
else:
self.out_no_data = im_mem.no_data
out_array = im_mem.array
out_mem = im_mem.osgeodata
for i in m_rules:
out_array = MaskCls(out_mem, i[0], i[1], val_assign).array
out_mem = save_map(out_array, "", im_mem.d_type, self.reference, format_out="MEM")
out_array = out_array.astype("int16")
self.array = out_array
def mask_im(self, mask_aoi, mask_aoi_vl, replace_im=None, reverse=False):
map_mem = save_map(self.array, "", gdal.GDT_UInt16, self.reference, format_out="MEM")
im_masked = MaskAOI(map_mem, mask_aoi, mask_aoi_vl, self.out_no_data,
replace_im=replace_im, reverse=reverse)
return im_masked
def save_im(self, output, format_out="GTiff"):
ds_out = save_map(self.array, output, gdal.GDT_UInt16, self.reference, out_no_data=self.out_no_data,
format_out=format_out)
if format_out == 'MEM':
return ds_out

This is the way I solved it using inheritance:
class Template:
def __init__(self):
self.array = None
self.reference = None
self.out_no_data = None
self.data_type = None
def mask(self, mask_aoi, mask_aoi_vl, replace_im=None, reverse=False):
map_mem = save_map(self.array, "", self.data_type, self.reference, format_out="MEM")
im_masked = MaskAOI(map_mem, mask_aoi, mask_aoi_vl, self.out_no_data,
replace_im=replace_im, reverse=reverse)
return im_masked
def save(self, output, format_out="GTiff"):
ds_out = save_map(self.array, output, self.data_type, self.reference, out_no_data=self.out_no_data,
format_out=format_out)
if format_out == 'MEM':
return ds_out
class MergeClasses(Template):
def __init__(self, input_data, m_classes, other_cls_val=None):
class_map1 = ReadMap(input_data)
self.reference = class_map1.reference
class_map1_array = class_map1.array
if class_map1.no_data is None:
self.out_no_data = 255
else:
self.out_no_data = class_map1.no_data
array_class = merge_cls(class_map1_array, m_classes, other_cls_val)
class_map_f = array_class.astype("int16")
self.array = class_map_f
self.data_type = gdal.GDT_UInt16

Related

【python】why parent variables address is the same in the child class object

The following is my python code. I think output_ports and input_ports have diffrent address.
class test():
def __init__(self) -> None:
pass
class INode(object):
node_name = "INode"
config = None
output_ports = []
input_ports = []
def __init__(self) -> None:
super().__init__()
pass
def NodeStart(slef):
pass
def GetOutputPort(self):
print(self)
index = len(self.output_ports)
# self.output_ports[index] = test()
self.output_ports.append(test())
# return self.output_ports[index]
def GetInputPort(self):
print(self)
index = len(self.output_ports)
self.input_ports.append(test())
class AdbCollectNode(INode):
def __init__(self) -> None:
super(AdbCollectNode, self).__init__()
self.node_name = "s"
pass
def LinkNode(node_output, node_input):
node_output.GetOutputPort()
node_input.GetInputPort()
if __name__ == '__main__':
adb_node = AdbCollectNode()
adb_node_1 = AdbCollectNode()
adb_node_2 = AdbCollectNode()
LinkNode(adb_node_1, adb_node_2)
LinkNode(adb_node_1, adb_node)
print(id(adb_node_1.input_ports))
print(id(adb_node.input_ports))
print(id(adb_node_2.input_ports))
print(id(adb_node_1.output_ports))
print(id(adb_node.output_ports))
print(id(adb_node_2.output_ports))
id() output as follow:
4549382592
4549382592
4549382592
4549356224
4549356224
4549356224
I think the subclass variables address are the same。 why not same?

Object has no attribute but attribute is defined

I have defined an attribute in a custom class, but I keep receiving an AttributeError when I try to access it.
class SMainWindow(QMainWindow):
def __init__(self):
# Constructor
super(SMainWindow, self).__init__()
self.myapp = PyQtApp()
self.layout = QVBoxLayout()
self.label_text = ''
self.settings = scrudb.retrieve_settings('current')
self.competition = self.retrieve_competition()
self.set_competition(self.competition.id)
self.label = QLabel(self.label_text)
self.button_scrutineer = QPushButton('Scrutineer Competition')
self.button_comps = QPushButton('Change Competition')
self.button_comp = QPushButton('Edit Competition Details')
self.button_dancers = QPushButton('Add/Edit Competitors')
self.button_judges = QPushButton('Add/Edit Judges')
self.button_dancerGroups = QPushButton(
'Define Competitor Groups & Dances')
self.button_import = QPushButton('Import CSV')
self.button_delete = QPushButton('Delete Competition')
self.button_exit = QPushButton('Exit')
self.button_comps.clicked.connect(self.select_competition)
self.button_delete.clicked.connect(self.delete_competition)
self.button_exit.clicked.connect(self.exit_app)
if (self.competition == None):
self.disable_buttons()
self.layout.addWidget(self.label)
self.layout.addWidget(self.button_scrutineer)
self.layout.addWidget(self.button_comps)
self.layout.addWidget(self.button_comp)
self.layout.addWidget(self.button_dancers)
self.layout.addWidget(self.button_judges)
self.layout.addWidget(self.button_dancerGroups)
self.layout.addWidget(self.button_import)
self.layout.addWidget(self.button_delete)
self.layout.addWidget(self.button_exit)
self.myapp.setLayout(self.layout)
def set_competition(self, comp_id):
self.competition = scrudb.retrieve_competition(comp_id)
if (self.competition != None):
self.label_text = ('<center>Competition:<br><strong>%s</strong><br>%8s<br>%s</center>' % (self.competition.name, self.get_formatted_date(self.competition.eventDate), self.competition.location))
self.label.setText(self.label_text)
self.settings.lastComp = self.competition.id
scrudb.set_settings(self.settings)
return self.competition
else:
self.label_text = ('<center>No Competition Selected</center>')
return None
File "/Users/majikpig/mu_code/src/main/python/scruinterface1.py", line 182, in set_competition
self.label.setText(self.label_text)
AttributeError: 'SMainWindow' object has no attribute 'label'
You need to change order of fields ... in set competition function you try to access field, which you haven't defined yet.
self.set_competition(self.competition.id)
self.label = QLabel(self.label_text)

Update linked issue customField when EPIC customField Change

I would like to update Issues in Epic based on custom field of the Epic I've tried reworking this over and over. I would like some assistance.
def linkType = "Issue in Epic"
def linkMgr = ComponentAccessor.getIssueLinkManager()
def cfManager = ComponentAccessor.getCustomFieldManager()
def issueManager = ComponentAccessor.getIssueManager()
def event = event as IssueEvent
Issue issue = event.issue as Issue
def accountField = cfManager.getCustomFieldObjects(issue)?.find{it.name == "Account"}
def cfValue = issue.getCustomFieldValue(accountField)
def epicLink = cfManager.getCustomFieldObjectByName("Epic Link")
def epicName = cfManager.getCustomFieldObjectByName("Epic Name")
def change = event?.changeLog?.getRelated("ChildChangeItem")?.find{it.field == accountField}
if (!change){
return
}
def linkedIssue = ComponentAccessor.issueLinkManager.getOutwardLinks(issue.id).findAll{it.issueLinkType.name == linkType}
if (!linkedIssue){
return
}
if (change){
linkedIssue.each{
def linkedIssueObj = it.destinationObject
def oldValue = linkedIssueObj.getCustomFieldValue(accountField)
def newValue = issue.getCustomFieldValue(accountField)
accountField.updateValue(null, linkedIssueObj, new ModifiedValue(oldValue, newValue), new DefaultIssueChangeHolder())
}
}

Python3 super not initializing __init__ attributes

I have the following code snippet:
class BaseUserAccount(object):
def __init__(self):
accountRefNo = "RefHDFC001"
FIType = "DEPOSIT"
pan = "AFF34964FFF"
mobile = "9822289017"
email = "manoja#cookiejar.co.in"
aadhar = "5555530495555"
class TestUserSavingsAccount(BaseUserAccount):
def __init__(self):
super().__init__()
accountNo = "HDFC111111111111"
accountTypeEnum = "SAVINGS"
def test_create_account(self):
request_body = """\
<UserAccountInfo>
<UserAccount accountRefNo="{}" accountNo="{}"
accountTypeEnum="{}" FIType="{}">
<Identifiers pan="{}" mobile="{}" email="{}" aadhar="{}"></Identifiers>
</UserAccount>
</UserAccountInfo>
""".format(self.accountRefNo, self.accountNo, self.accountTypeEnum,
self.FIType, self.pan, self.mobile, self.email, self.aadhar)
If I run this code in the interactive shell:
>>> t = TestUserSavingsAccount()
>>> t.accountRefNo
AttributeError: 'TestUserSavingsAccount' object has no attribute 'accountRefNo'
>>> t.accountNo
AttributeError: 'TestUserSavingsAccount' object has no attribute 'accountNo'
Seeing the above behavior, it seems like the super is neither setting up values from the base class and neither the attributes of the child (accountNo, accountTypeEnum) are being set.
The way you wrote only assign those values to local variables. You need to initialize attributes of the self object instead:
class BaseUserAccount(object):
def __init__(self):
self.accountRefNo = "RefHDFC001"
self.FIType = "DEPOSIT"
self.pan = "AFF34964FFF"
self.mobile = "9822289017"
self.email = "manoja#cookiejar.co.in"
self.aadhar = "5555530495555"
class TestUserSavingsAccount(BaseUserAccount):
def __init__(self):
super().__init__()
self.accountNo = "HDFC111111111111"
self.accountTypeEnum = "SAVINGS"

Instances ship attributes to other instances after construction

I was looking for a way to access configuration file entries from instance- resp. class-bound variables. Therefor I have created the following module:
from ..lib.files import ConfigFile
from abc import abstractmethod
__all__ = ['ClassConfig',
'InstanceConfig',
'Configurable']
class ConfigEntry():
"""
A Config entry
"""
__value = None
def __init__(self, value=None):
"""
Initializes the
"""
self.__value = value
def __set__(self, __, value):
self.__value = value
#property
def value(self):
"""
Returns the value
"""
return self.__value
class ClassConfig(ConfigEntry):
"""
A class config entry
"""
def __get__(self, obj, cls):
"""
Returns its value, when called by a class, else itself
"""
if obj == None:
return self.value
else:
return self
class InstanceConfig(ConfigEntry):
"""
An instance config entry
"""
def __get__(self, obj, cls):
"""
Returns its value, when called by an instance, else itself
"""
if obj != None:
return self.value
else:
return self
class Configurable():
"""
Configuration file binding
"""
__SUFFIX = '.conf'
__TYPES = {int: 'int',
float: 'float',
str: 'str',
bool: 'bool'}
__file_ = None
__lbi = '['
__lei = ']'
__ls = ','
__ts = '←'
__loaded = False
def __init__(self, path, suffix=None):
"""
Initialize the config file
"""
# Initializes instance methods
self.__setinstattr()
suffix = suffix if suffix != None else self.__SUFFIX
self.__file_ = ConfigFile(path + suffix)
self.load()
def __setinstattr(self):
"""
Set instance attributes
"""
self.__fields = self.__inst___fields
self._file = self.__inst____file
self._force_load = self.__inst__force_load
self.load = self.__inst_load
self.store = self.__inst_store
#staticmethod
def __filter(attrs):
return [a for a in attrs
if a == a.upper()
and not a.startswith('_')]
#staticmethod
def __encode(val):
"""
Encode a value
"""
t = type(val)
if t == list:
return Configurable.__lbi + \
Configurable.__ls.join([Configurable.__encode(i)
for i in val]) \
+ Configurable.__lei
elif val == None:
return None
else:
return Configurable.__ts.join([str(val),
Configurable.__TYPES.get(t, '?')])
#staticmethod
def __decode(val):
"""
Decode a value
"""
def det_type(token):
"""
Determine the type of a token
"""
t = token.strip().split(Configurable.__ts)
if len(t) == 2:
raw_val = t[0]
tpe = t[1]
if tpe == Configurable.__TYPES[str]:
return str(raw_val)
elif tpe == Configurable.__TYPES[int]:
return int(raw_val)
elif tpe == Configurable.__TYPES[float]:
return float(raw_val)
elif tpe == Configurable.__TYPES[bool]:
return True if raw_val.lower() in ['1',
'true',
't'] else False
else:
try:
return int(raw_val)
except:
try:
return float(raw_val)
except:
return raw_val
return token
def str2list(s):
"""
Try to parse a list from a string
"""
def getlist(val):
"""
Get a list from a reversed character list of a string
"""
result = []
token = ''
while val:
c = val.pop()
if c == Configurable.__lei:
token = Configurable.__lei
result = [getlist(val)] + result
elif c == Configurable.__lbi:
if (not Configurable.__lbi in token) and (not Configurable.__lei in token):
result = [det_type(token)] + result
token = c
return result
elif c == Configurable.__ls:
if (not Configurable.__lbi in token) and (not Configurable.__lei in token):
result = [det_type(token)] + result
token = ''
else:
token = c + token
if token:
result = [det_type(token)] + result
return result
l = []
for char in s:
l.append(char)
l = getlist(l)
if len(l) == 0:
return l
return l.pop()
return str2list(val)
#classmethod
def __fields(cls):
"""
Get fields for an instance
"""
result = {}
class Subclass(cls):
def __init__(self):
pass
instance = Subclass()
attrs = Configurable.__filter(dir(instance))
for a in attrs:
aval = getattr(instance, a)
if isinstance(aval, ClassConfig):
value = getattr(cls, a)
result[a] = value
return result
def __inst___fields(self):
"""
Get fields of an instance
"""
result = {}
cls = self.__class__
attrs = Configurable.__filter(dir(cls))
for a in attrs:
val = getattr(cls, a)
if isinstance(val, InstanceConfig):
value = getattr(self, a)
result[a] = value
return result
#classmethod
#abstractmethod
def _file(cls):
"""
Returns the file
XXX: Implement by calling
super()._file(static_path)
"""
pass
#classmethod
def _file_path(cls, path, suffix=None):
"""
Returns the file relative to a path
"""
suffix = suffix if suffix != None else cls.__SUFFIX
f = ConfigFile(path + suffix)
f.create()
return f
def __inst____file(self):
"""
Returns the file
"""
return self.__file_
#classmethod
def load(cls):
"""
Loads the config file content, if not yet done into the class
"""
if not cls.__loaded:
return cls._force_load()
return True
def __inst_load(self):
"""
Loads the config file content, if not yet done into the instance
"""
if not self.__loaded:
return self._force_load()
return True
#classmethod
def _force_load(cls):
"""
Loads the config file's content to the class
"""
if cls._file().exists:
data = cls._file().dict()
for field in Configurable.__filter(data):
setattr(cls, field,
Configurable.__decode(data[field]))
cls.__loaded = True
return True
return False
def __inst__force_load(self):
"""
Loads the config file's content to the instance
"""
if self._file().exists:
data = self._file().dict()
for field in Configurable.__filter(data):
setattr(self, field,
Configurable.__decode(data[field]))
self.__loaded = True
return True
return False
#classmethod
def store(cls):
"""
Writes class config to file
"""
result = True
content = cls.__fields()
if not cls._file().exists:
cls._file().create()
for new_field in content:
set_result = cls._file().set(new_field,
Configurable.__encode(content[new_field]))
result = False if not set_result else result
return result
def __inst_store(self):
"""
Writes instance config to file
"""
result = True
content = self.__fields()
if not self._file().exists:
self._file().create()
for new_field in content:
set_result = self._file().set(new_field,
Configurable.__encode(content[new_field]))
result = False if not set_result else result
return result
The Configurable class is now inherited by several sub-classes, which may have global configuration (the class-bound stuff) and user-dependen configuration (the instance-bound stuff) like that:
class Spam(Configurable):
EGGS = InstanceConfig('foo')
GLOBAL_EGGS = ClassConfig('bar')
Now I face the problem, that each time a load() is performed on many instances in sequence, the InstanceConfigEntry will copy the value from the previuos instance:
class RETARD(Daemon):
"""
Real Estate Translation, Archiving and Redirection Daemon
"""
__source = None # The source interface instance
__targets = [] # The target interface instances
__locked = False # System locked state flag
__start_time = None # Start time of loop
__sleeping = 0 # Remaining time to sleep
#===========================================================================
# Default customer config
#===========================================================================
SOURCE = InstanceConfig('') # Name of the source interface
TARGETS = InstanceConfig([]) # Names of the target interfaces
INTERVAL = InstanceConfig(120.0) # Loop interval
DEBUG = InstanceConfig(False) # Print the import config?
def __init__(self, customer):
"""
Constructor
"""
print('SOURCE1: ' + str(self.SOURCE))
super().__init__(customer)
print('SOURCE2: ' + str(self.SOURCE))
self.__load()
print('SOURCE3: ' + str(self.SOURCE))
# Disable logger on high level to prevent PyXB
# from printing messages to the terminal
logging.disable(9999)
<SNIP>
When loaded like this (daemons contains four different instances):
daemons = []
for customer in customers:
daemons.append(RETARD(customer))
It will produce this output:
SOURCE1:
SOURCE2: IS24
SOURCE3: IS24
SOURCE1: IS24
SOURCE2: is24
SOURCE3: is24
SOURCE1: is24
SOURCE2: infobase
SOURCE3: infobase
SOURCE1: infobase
SOURCE2: infobase
SOURCE3: infobase
I do not understand this behaviour, since I did not change the class' attributes anywhere but just those of the instances.
How can I avoid the instances to ship their changed attributes to the next instance?
The problem here, wich I did not realize was, that the InstanceConfig and ClassConfig entries as bound to the class at the time, the module is loaded. When I assigned other content to the respective attributes during runtime from within an instance, it of course just changed the content of the still class-bound *Config instance.
I worked arund this issue by defaulting values iff they are not contained within the respective config file like so:
from ..lib.files import ConfigFile
from abc import abstractmethod
__all__ = ['ClassConfig',
'InstanceConfig',
'Configurable']
class ConfigEntry():
"""
A Config entry
"""
__value = None
__default = None
def __init__(self, default=None):
"""
Initializes the
"""
self.__default = default
self.__value = default
def __set__(self, __, value):
"""
Sets the value
"""
self.__value = value
#property
def value(self):
"""
Returns the value
"""
return self.__value
#property
def default(self):
"""
Access default value
"""
return self.__default
class ClassConfig(ConfigEntry):
"""
A class config entry
"""
def __get__(self, obj, cls):
"""
Returns its value, when called by a class, else itself
"""
if obj == None:
return self.value
else:
return self
class InstanceConfig(ConfigEntry):
"""
An instance config entry
"""
def __get__(self, obj, cls):
"""
Returns its value, when called by an instance, else itself
"""
if obj != None:
return self.value
else:
return self
class Configurable():
"""
Configuration file binding
"""
__SUFFIX = '.conf'
__TYPES = {int: 'int',
float: 'float',
str: 'str',
bool: 'bool'}
__file_ = None
__lbi = '[' # List begin identifier
__lei = ']' # List end identifier
__ls = ',' # List separator
__ts = '←' # Type separator
__loaded = False
def __init__(self, path, suffix=None):
"""
Initialize the config file
"""
# Initializes instance methods
self.__setinstattr()
suffix = suffix if suffix != None else self.__SUFFIX
self.__file_ = ConfigFile(path + suffix)
self.load()
def __setinstattr(self):
"""
Set instance attributes
"""
self.__fields = self.__inst___fields
self._file = self.__inst____file
self._force_load = self.__inst__force_load
self.load = self.__inst_load
self.store = self.__inst_store
#staticmethod
def __filter(attrs):
return [a for a in attrs
if a == a.upper()
and not a.startswith('_')]
#staticmethod
def __encode(val):
"""
Encode a value
"""
t = type(val)
if t == list:
return Configurable.__lbi + \
Configurable.__ls.join([Configurable.__encode(i)
for i in val]) \
+ Configurable.__lei
elif val == None:
return None
else:
return Configurable.__ts.join([str(val),
Configurable.__TYPES.get(t, '?')])
#staticmethod
def __decode(val):
"""
Decode a value
"""
def det_type(token):
"""
Determine the type of a token
"""
t = token.strip().split(Configurable.__ts)
if len(t) == 2:
raw_val = t[0]
tpe = t[1]
if tpe == Configurable.__TYPES[str]:
return str(raw_val)
elif tpe == Configurable.__TYPES[int]:
return int(raw_val)
elif tpe == Configurable.__TYPES[float]:
return float(raw_val)
elif tpe == Configurable.__TYPES[bool]:
return True if raw_val.lower() in ['1',
'true',
't'] else False
else:
try:
return int(raw_val)
except:
try:
return float(raw_val)
except:
return raw_val
return token
def str2list(s):
"""
Try to parse a list from a string
"""
def getlist(val):
"""
Get a list from a reversed character list of a string
"""
result = []
token = ''
while val:
c = val.pop()
if c == Configurable.__lei:
token = Configurable.__lei
result = [getlist(val)] + result
elif c == Configurable.__lbi:
if (not Configurable.__lbi in token) and (not Configurable.__lei in token):
result = [det_type(token)] + result
token = c
return result
elif c == Configurable.__ls:
if (not Configurable.__lbi in token) and (not Configurable.__lei in token):
result = [det_type(token)] + result
token = ''
else:
token = c + token
if token:
result = [det_type(token)] + result
return result
l = []
for char in s:
l.append(char)
l = getlist(l)
if len(l) == 0:
return l
return l.pop()
return str2list(val)
#classmethod
def __fields(cls):
"""
Get fields for an instance
"""
result = {}
class Subclass(cls):
def __init__(self):
pass
instance = Subclass()
attrs = Configurable.__filter(dir(instance))
for a in attrs:
aval = getattr(instance, a)
if isinstance(aval, ClassConfig):
result[a] = aval
return result
def __inst___fields(self):
"""
Get fields of an instance
"""
result = {}
cls = self.__class__
attrs = Configurable.__filter(dir(cls))
for a in attrs:
val = getattr(cls, a)
if isinstance(val, InstanceConfig):
result[a] = val
return result
#classmethod
#abstractmethod
def _file(cls):
"""
Returns the file
XXX: Implement by calling
super()._file(static_path)
"""
pass
#classmethod
def _file_path(cls, path, suffix=None):
"""
Returns the file relative to a path
"""
suffix = suffix if suffix != None else cls.__SUFFIX
f = ConfigFile(path + suffix)
f.create()
return f
def __inst____file(self):
"""
Returns the file
"""
return self.__file_
#classmethod
def load(cls):
"""
Loads the config file content, if not yet done into the class
"""
if not cls.__loaded:
return cls._force_load()
return True
def __inst_load(self):
"""
Loads the config file content, if not yet done into the instance
"""
if not self.__loaded:
return self._force_load()
return True
#classmethod
def _force_load(cls):
"""
Loads the config file's content to the class
"""
if cls._file().exists:
data = cls._file().dict()
else:
data = {}
fields = cls.__fields()
for field in fields:
val = data.get(field)
if val == None:
val = fields[field].default
else:
val = Configurable.__decode(val)
setattr(cls, field, val)
cls.__loaded = True
return True
def __inst__force_load(self):
"""
Loads the config file's content to the instance
"""
if self._file().exists:
data = self._file().dict()
else:
data = {}
fields = self.__fields()
for field in fields:
val = data.get(field)
if val == None:
val = fields[field].default
else:
val = Configurable.__decode(val)
setattr(self, field, val)
self.__loaded = True
return True
#classmethod
def store(cls):
"""
Writes class config to file
"""
result = True
fields = cls.__fields()
if not cls._file().exists:
cls._file().create()
for field in fields:
val = fields[field].value
set_result = cls._file().set(field,
Configurable.__encode(val))
result = False if not set_result else result
return result
def __inst_store(self):
"""
Writes instance config to file
"""
result = True
fields = self.__fields()
if not self._file().exists:
self._file().create()
for field in fields:
val = fields[field].value
set_result = self._file().set(field,
Configurable.__encode(val))
result = False if not set_result else result
return result

Resources