Universal override property - python-3.x

In Python3, I would like to create a class with an override-property, so after instantiation, the instance will behave like whatever it is being assigned, unless its override property is assigned something else than None, in which case it will behave like what has been assigned to the override property. E.g.
x = OverrideClass()
x = 1
print(x) -> 1
x.override = “abc“
print(x) -> abc
x = 2
print(x) -> abc
x.override = None
print(x) -> 2
Can this be done? From what I've learned by now, it is not possible to override the x = y assignment. So the only way would be to modify Python's built-in classes in question. Adding an override-property to int and float would probably do in my application. Is that possible somehow?

Related

AST: check if two nodes are connected

I am parsing some code as below. I get a list of ast.node. Now, I want to know which nodes are linked to which node. Is it possible to do that?
Example in below code: 1st assign is not connected (f = lambda..) to any other assign. But 2nd assign and FunctioDef are connected. Is it possible to infer this from some node attribute?
Assuming of course there is no other definition or code outside this.
code = '''
f = lambda x : x
factor = 2
def f(arg):
if arg == 0:
return 1
return factor*arg*f(arg-1)
'''
parsed = ast.parse(code)
>>> parsed.body
[<_ast.Assign at 0x7f9c81f0e670>,
<_ast.Assign at 0x7f9c92042070>,
<_ast.FunctionDef at 0x7f9c920421f0>]

A small question about the change() function,how to understand the process about it?

I am learning the basic usage of python,and I'm confusing about how the variable runs in a practice question. Here are the code below:
x = 1
def change(a):
a = x + 1
print(x)
change(x)
x = 1
def change(a)
x = x + 1
print(x)
change(x)
This is how I think the process:
in the first code:change(x) means: x = x + 1 - print (x) - output:2
but in fact the result is 1.So the real process is: x(symbol in the function) = x(global variable) + 1, print(x), this x is the global variable.
is that right?
in the second code,I think still the output should be 2,but it shows me that UnboundLocalError: local variable 'x' referenced before assignment
so in the python,we can't use function to change the global variable?
Inside a function, you can read global variables but you cannot modify them without explicitly declaring them as global like this:
x = 1
def change(a):
global x # <- this is required since you're assigning a new value to x
x = x + 1
print(x)
change(x)
In the first case, with a = x + 1, the global declaration is not required since you're only reading the value of x, not modifying it. Also, the output is 1 in the first case, since you're printing x not a.

how do i write multiple function outputs to single csv file

i am scraping multiple websites so i am using one function for each website script, so each function returns 4 values, i want to print them in dataframe and write them in csv but i am facing this problem, i may be asking something too odd or basic but please help
Either i will have to write whole script in one block and that will look very nasty to handle so if i could find a way around, this is just a sample of problem i am facing..
def a1(x):
z=x+1
r = x+2
print(z, r)
def a2(x):
y=x+4
t=x+3
print(y, t)
x = 2
a1(x)
a2(x)
3 4
6 5
data = pd.Dataframe({'first' : [z],
'second' : [r],
'third' : [y],
'fourth' : [t]
})`
data
*error 'z' is not defined*
You may find it convenient to write functions that return a list of dicts.
For example:
rows = [dict(a=1, b=2, c=3),
dict(a=4, b=5, c=6)]
df = pd.DataFrame(rows)
The variables are only defined in the local scope of your functions, you'd either need to declare them globally or - the better way - return them so you can use them outside of the function by assigning the return values to new variables
import pandas as pd
def a1(x):
z = x+1
r = x+2
return (z, r)
def a2(x):
y = x+4
t = x+3
return (y, t)
x = 2
z, r = a1(x)
y, t = a2(x)
data = pd.DataFrame({'first' : [z],
'second' : [r],
'third' : [y],
'fourth' : [t]
})

How can I use mypy's typechecking to enforce the signature of a callable type

I have a function that takes another function x as its argument. Function x can have 2 different types of signatures and I would like to enforce this through type hinting:
TYPE_A = Callable[[int, int], int]
TYPE_B = Callable[[int], int]
def my_func(x: Union[TYPE_A, TYPE_B]) -> None:
...determine x is of which type and use x accordingly...
I am running into 2 problems:
I don't know how to check whether x is of TYPE_A or TYPE_B. I tried using isinstance(x, TYPE_A) and it generates a type error.
If I am using another way to determine the type of x, for instance, using signature to determine the signature of x inside my_func (if x has 1 parameter or 2 parameters), mypy still thinks there is a type error whenever I run x:
from inspect import signature
def my_func(x: Union[TYPE_A, TYPE_B]):
sig = signature(x)
if len(sig.parameters.values()) == 1:
x(1) // mypy thinks this is a type error: too few args
else:
x(1, 2) // mypy thinks this is type error: too many args
Is there a way for me to write a function that takes another function as its input, and use type checking to enforce that the input function has the correct signature?
Unfortunately, it does seem like there is currently no way for mypy to infer the correct type for x, so I think the best that you can do is to use typing.cast to force x to the desired type:
from typing import *
from inspect import signature
TYPE_A = Callable[[int, int], int]
TYPE_B = Callable[[int], int]
def my_func(x: Union[TYPE_A, TYPE_B]):
sig = signature(x)
if len(sig.parameters.values()) == 1:
x = cast(TYPE_B, x)
x(1)
else:
x = cast(TYPE_A, x)
x(1, 2)

Apply closure as a class method

Suppose there is a function def f = { x -> x + 4 }.
Is there a way to call it somehow like 7.f() and get 11?
Yes, you can add that function as a method to the Integer class, but, instead of using the x variable, you are better using the delegate of the closure:
Integer.metaClass.f = { delegate + 4 }
assert 7.f() == 11

Resources