Can you generate new self names inside a class? - python-3.x

Trying to figure out how to use a function to generate new self named variables inside a class.
I've played around with it in IDLE, and searched online docs. Solution is alluding me.
>>> import random
>>> abc = [(map(chr,range(ord('A'),ord('Z')+1)))+(map(chr,range(ord('a'),ord('z')+1)))]
>>> class Test():
def __init__(self, abc):
self.a = 0
self.abc = abc
def newSelf(self):
for i in range(2):
b = random.choice(abc)
c = random.choice(abc)
globals()['self.'+b+c] = 0
#or
locals()['self.'+b+c] = 0
print(b+c,0)
>>> example = Test(abc)
>>> example.a
0
>>> example.newSelf() #say it generates
An 0
ze 0
>>> example.An #calling new self variable of example object returns
Traceback (most recent call last):
File "<pyshell#221>", line 1, in <module>
example.An
AttributeError: 'Test' object has no attribute 'An'
# I'm hoping for...
>>> example.An
0

Using setattr:
You can use setattr to set the new attribute:
>>> class Test():
... def __init__(self, abc):
... self.a = 0
... self.abc = abc
... def newSelf(self):
... for i in range(2):
... b = random.choice(abc)
... c = random.choice(abc)
... setattr(self, b+c, 0)
... print(b+c,0)
And the attribute will again be available:
>>> example = Test(abc)
>>> example.newSelf()
zM 0
Ja 0
>>> example.zM
0
>>> example.Ja
0
Using exec:
You can use exec function to execute a python statement stored in a string. As, you are generating the variable name randomly, you can create the whole python statement in a string, and execute that statement using exec like below:
>>> class Test():
... def __init__(self, abc):
... self.a = 0
... self.abc = abc
... def newSelf(self):
... for i in range(2):
... b = random.choice(abc)
... c = random.choice(abc)
... exec('self.'+b+c+' = 0')
... print(b+c,0)
Here, I have created the new attribute using exec('self.'+b+c+' = 0'). Now, after calling this method, the attribute will be available:
>>> example = Test(abc)
>>> example.newSelf()
Tw 0
Xt 0
>>> example.Tw
0
>>> example.Xt
0

Related

How do l load a csv from a class/def function, and how do I then make it read/print both rows and columns?

I have a utils.py and a main.py. In the utils.py file I want all my data load, formula defs and so on. I want to create a class Data_load() and make that ensure load of data I can pull directly from main.py.
I have this:
utils.py:
def readMyFile(filename):
file = []
with open(filename) as csvDataFile:
csvReader = csv.reader(csvDataFile, delimiter=';', )
for row in csvReader:
file.append(row[0])
return file
file = readMyFile('C:\\...\\count_all_terminate.csv')
file_load = pd.DataFrame(file)
Got this:
main.py reads (one column only and with no header??!!):
0
0 User Name
1 146166
2 146166
3 146166
4 146166
... ...
3987 200589
3988 194018
3989 194449
3990 174565
3991 175440
I wanted main.py to read this:
0 col 2 col 3 col n
0 User Name
1 146166
2 146166
3 146166
4 146166
... ...
3987 200589
3988 194018
3989 194449
3990 174565
3991 175440
How do I
place the def in class, something like the following...
class Data_load():
def __init__(self, ....):
self
def readMyFile(filename):
file = []
with open(filename) as csvDataFile:
csvReader = csv.reader(csvDataFile, delimiter=';', )
for row in csvReader:
file.append(row[0])
return file
..and how do I make it print all the columns I know to exist in the 'count_all_terminate.csv' file? Any help is appreciated, Happy New Year from Hubsandspokes
If you want to use a class, I would employ pandas. You could do it standalone as follows:
import pandas as pd
df = pd.DataFrame.read_csv(filepath, **kargs) #see docs for **kargs definitions
df_stats = df.describe() #Provides summary statistics on each column see docs for
# description
If you desire a class,
class Data_load:
def __init__(self, filepath, **kargs):
self.df = pd.read_csv(filepath, **kargs)
def summary_stats(self):
return seld.df.describe()
Then to use:
filepath = r"path to csv file of interest"
myData = Data_load(filepath)
EDA = myData.summary_stats()

Accessing Class attribute from a called function?

Let say I have something like this :
--module1
def called():
if caller.class.attrX == 1 : ...
--module2
class ABC:
attrX = 1
def method():
called()
I want to access caller Class-attribute ?
I know I have to use inspect somehow but can figure how exactly.
python3
Passing a variable to the function is the best (and only?) option.
--module1
def called(attrX):
if attrX == 1 : ...
--module2
class ABC:
self.attrX = 1
def method():
called(self.attrX)
This seems to work for object variable :
/if I can make it work for class-var it will be better/
import inspect
def say(*args, **kwargs) :
obj = inspect.currentframe().f_back.f_locals['self']
if hasattr(obj,'aaa') : print('hasit')
else : print("no")
class ABC:
aaa = 2
def test(self):
say(123)
i.e. if I dont have 'aaa' set in advance :
In [8]: a.test()
no
In [9]: ABC.aaa = 2
In [10]: a.test()
no
In [12]: a.aaa = 3
In [13]: a.test()
hasit

Python regular expressions: Better way to handle non-matches?

When I deal with regular expressions, my code is littered with conditionals so as to not create exceptions when a pattern is not found:
m = some_compiled_pattern.match(s)
if m:
x = m.groups()
do_something_with(x)
m = some_other_compiled_pattern.search(s):
if m:
y = m.groupdict()
else:
y = {}
do_something_else_with(y)
Isn't there a better (less verbose) way to handle such exceptions?
You might find this class useful to reduce most of those if-no-match handling to a one line.
class Returns:
"""
Makes an object that pretends to have all possible methods,
but returns the same value (default None) no matter what this method,
or its arguments, is.
"""
def __init__(self, return_val=None):
self.return_val = return_val
def the_only_method_there_is(*args, **kwargs):
return return_val
self.the_only_method_there_is = MethodType(the_only_method_there_is, self)
def __getattr__(self, item):
if not item.startswith('_') and item not in {'return_val', 'the_only_method_there_id'}:
return self.the_only_method_there_is
else:
return getattr(self, item)
Example use:
>>> import re
>>> p = re.compile(r'(\d+)\W+(\w+)')
>>>
>>> # when all goes well...
>>> m = p.search('The number 42 is mentioned often')
>>> num, next_word = m.groups()
>>> num, next_word
('42', 'is')
>>>
>>> # when the pattern is not found...
>>> m = p.search('No number here')
>>> assert m is None # m is None so...
>>> num, next_word = m.groups() # ... this is going to choke
Traceback (most recent call last):
...
AttributeError: 'NoneType' object has no attribute 'groups'
>>>
>>> # Returns to the rescue
>>> num, next_word = (p.search('No number here') or Returns((None, 'default_word'))).groups()
>>> assert num is None
>>> next_word
'default_word'
EDIT: See this gist for a longer discussion (and alternate but similar solution) of this problem.

Python 3: Invalid Syntax Error when using * operator in __init__ between pre-defined values defined in-scope

I am getting a syntax error when trying to do the following MCVE in Python 3.
HEIGHT = 26
WIDTH = 26
OTHERVAR = 5
class Foo():
def __init__(self, OTHERVAR, HEIGHT*WIDTH):
print (str(OTHERVAR + HEIGHT*WIDTH))
foo_inst = Foo()
Below is the error
File "a.py", line 6
def __init__(self, OTHERVAR, HEIGHT*WIDTH):
^
SyntaxError: invalid syntax
I'm wondering why the multiplication * operator is invalid syntax in this scenario.
If someone could explain why this is bad syntax and offer a potential workaround, that would be great. Thank you.
A function parameter supposes to be a variable, your HEIGHT*WIDTH produces a value, not a variable.
Are you probably looking for this (default value)?
>>> a = 1
>>> b = 2
>>> def test(c=a*b):
... print(c)
...
>>> test()
2
>>> def test(c=a*b, d):
... print(c, d)
...
File "<stdin>", line 1
SyntaxError: non-default argument follows default argument
>>> def test(d, c=a*b):
... print(d, c)
...
>>> test(10)
(10, 2)
And called by named parameters
>>> def test(d, c=a*b, e=20):
... print(d, c, e)
...
>>> test(10, e=30)
(10, 2, 30)

python3: getting defined functions from a code object?

In python3, I have the following code:
path = '/path/to/file/containing/python/code'
source = open(path, 'r').read()
codeobject = compile(source, path, 'exec')
I have examined codeobject, but I don't see any way to get a list of all the functions that are defined within that object.
I know I can search the source string for lines that begin with def, but I want to get this info from the code object, if at all possible.
What am I missing?
A code object is a nested structure; functions are created when the code object is executed, with their bodies embedded as separate code objects that are part of the constants:
>>> example = '''\
... def foobar():
... print('Hello world!')
... '''
>>> codeobject = compile(example, '', 'exec')
>>> codeobject
<code object <module> at 0x11049ff60, file "", line 1>
>>> codeobject.co_consts
(<code object foobar at 0x11049fe40, file "", line 1>, 'foobar', None)
>>> codeobject.co_consts[0]
<code object foobar at 0x11049fe40, file "", line 1>
>>> codeobject.co_consts[0].co_name
'foobar'
When you disassemble the top-level code object you can see that the function objects are created from such code objects:
>>> import dis
>>> dis.dis(codeobject)
1 0 LOAD_CONST 0 (<code object foobar at 0x11049fe40, file "", line 1>)
2 LOAD_CONST 1 ('foobar')
4 MAKE_FUNCTION 0
6 STORE_NAME 0 (foobar)
8 LOAD_CONST 2 (None)
10 RETURN_VALUE
The MAKE_FUNCTION opcode takes the code object from the stack, as well as the function name and any default argument values from the stack; you can see the LOAD_CONST opcodes preceding it that put the code object and name there.
Not all code objects are functions however:
>>> compile('[i for i in range(10)]', '', 'exec').co_consts
(<code object <listcomp> at 0x1105cb030, file "", line 1>, '<listcomp>', 10, None)
>>> compile('class Foo: pass', '', 'exec').co_consts
(<code object Foo at 0x1105cb0c0, file "", line 1>, 'Foo', None)
If you wanted to list what functions are loaded in the bytecode, your best bet is to use the disassembly, not look for code objects:
import dis
from itertools import islice
# old itertools example to create a sliding window over a generator
def window(seq, n=2):
"""Returns a sliding window (of width n) over data from the iterable
s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...
"""
it = iter(seq)
result = tuple(islice(it, n))
if len(result) == n:
yield result
for elem in it:
result = result[1:] + (elem,)
yield result
def extract_functions(codeobject):
codetype = type(codeobject)
signature = ('LOAD_CONST', 'LOAD_CONST', 'MAKE_FUNCTION', 'STORE_NAME')
for op1, op2, op3, op4 in window(dis.get_instructions(codeobject), 4):
if (op1.opname, op2.opname, op3.opname, op4.opname) == signature:
# Function loaded
fname = op2.argval
assert isinstance(op1.argval, codetype)
yield fname, op1.argval
This generates (name, codeobject) tuples for all functions that are loaded in a given code object.

Resources