Viewing class definition of built-in classes in Python like Symbol - python

I am very new to Python (switching from Matlab) and I am currently working with the SymPy package. I realised that I can calculate the derivate of a function with f.diff(x), even when I have not imported the diff function. So, basically f.diff(x) works but diff(f,x) returns an error.
from sympy import symbols
x = symbols('x')
f = x**2 + 1
f.diff(x)
The reason that I could think of was that diff is actually defined as a method attribute for the class Symbol and thus, f.diff(x) works as long as x is of Symbol type and f has been defined using x. Is there a way to somehow view the Symbol class definition in order to verify that a diff method attribute actually exists?

The reason that I could think of was that diff is actually defined as a method attribute for the class Symbol and thus, f.diff(x) works as long as x is of Symbol type and f has been defined using x.
This is mostly correct (corrections below).
In contrast to Matlab, Python uses namespaces. This means that you only have very basic functions, classes, etc. available by default and everything else needs to be imported into the main namespace or is only available with a “prefix” specifying the namespace. What you gain from this is that you avoid name clashes and it’s easy to trace from which module a function is coming. For instance, in your example, the reader can see that symbols was imported from the sympy module (into the main namespace). This module also has a diff function (not the method) that you could use after importing with from sympy import diff.
In this sense, each object comes along with its own namespace, which is for most practical purposes determined by its class¹.
Functions in this namespace are called methods and (usually) do something on the object itself or using the specifics of the object itself.
Now, for the promised corrections or clarifications:
It is f’s class which is relevant here, not x’s.
You can see the class of f with type(f) and it is Add (residing in sympy.core.add).
This is because it is primarily a sum (of x**2 and 1).
More importantly, Add is a subclass of Expr (expression), which is the parent class for all SymPy expressions.
For example, the class Symbol is also a subclass of Expr.
(You can see this with type(f).mro().)
And this is the important thing here: All SymPy expressions have the diff method.
It is actually not relevant that the argument of f.diff is a Symbol or Expr.
It only needs to be something that SymPy can reasonably interpret as one.
For example f.diff("x") also works, because SymPy can translate the string "x" to a Symbol that is equivalent to your x.
Is there a way to somehow view the Symbol class definition in order to verify that a diff method attribute actually exists?
Yes. The easiest way is the basic Python function dir, which returns a list of all attributes (everything accessible by the . operator) of an object. Typically, most of these are methods. In you case, you can just call dir(f). Note that this lists also contains quite some attributes starting with _, which indicates that they are not designated for user consumption. In any reasonable programming environment (IDE, IPython, Jupyter), this list is also shown to you when you use tab completion (F, ., Tab).
However, while learning about a class by going through all its methods is usually a good approach, for SymPy expressions this is not feasible.
There is a lot of things somebody could want to do with these expressions, but you will only ever use a fraction of them.
Instead, you can either guess the name of the method and thus narrow down your search considerable.
For example, you can guess that the method for differentiation starts with a d (be it for differentiate or derivative), and here the tab completion (F, ., D, Tab) only gives you four results instead of three hundred.
Another approach is that you start searching the documentation (or the Internet in general) with what your operation of interest (here differentiating) instead of your the object of your operation (here, SymPy expressions, i.e., instances of Expr). After all SymPy is all about the latter, so that is kind of a given.
Finally, normally there is a documentation of a class featuring all its methods.
For Expr, this is here.
Unfortunately, in case of Expr the documentation is not exhaustive, e.g., it lacks the diff method.
While this is not ideal, it is somewhat understandable given the amount of methods as well as the duality of methods and functions of SymPy: For most methods of Expr, an analogous function can be directly imported from sympy.
¹ You can also just add stuff there (symbols.wrzlprmft = "foo"), but that’s a pretty advanced and rare usage. Also some classes are made to block this, e.g., you cannot do f.wrzlprmft = "foo".

Related

Can you create an abstract data type that is *not* in a class?

This is just a question that is a curiosity as I was reviewing OOP. Can you have an ADT that is not in a class? So it'd all be separate functions. The language (it shouldn't matter, but in case it does) that I'm thinking in is Python 3.
No. A data type (in Python at least) is by definition a class. In C, you have to simulate object-orientedness by having individual functions, but there still has to be a struct to hold the data. Otherwise, there's no "data type".
Within the Python language, a data type is a class (with certain properties), so the trivial answer is no. In particular, one major characteristic that differentiates class (or data type) functionality from simple function calls, is that the defined data operations work seamlessly on the data type, or with trivial syntax, rather than having to specify every operation and operand in an explicit call.
Consider the statements:
# Fully functional, implicit data type operation
z = x + y
# Explicit data type operation, still within the class
z = x.add(y)
# Function call
z = add(x, y)
In the third instance, you have none of the built-in protections or encapsulations that come with a class. You can have a set of functions that just happen to coordinate to give you the desired results, but this is not an abstract data type.

Calling library functions in python

Case I: In some cases, I use the library name to call some set of function i.e, np.median().
Case II: And in some cases, I use the variable name and library name to call another set of function i.e, np.mean(heights) or heights.mean().
In case II, I am able to use both library name and variable name. In case I, only library name works.
My doubt is how to differentiate these tow sets of functions.
If I am wrong in anyway, please clear my thoughts.
(here i am referring to python language)
thank you.
In the first case you’re calling a method (function) of the library. Libraries are usually class instances or collections of functions within a module.
In the second example instead, you’re again calling a function from the module but in this case it returns a ndarray (a numpy list basically) which itself has some methods that can be called on it.

Python: `locals()` as a default function argument

Suppose I have a module PyFoo.py that has a function bar. I want bar to print all of the local variables associated with the namespace that called it.
For example:
#! /usr/bin/env python
import PyFoo as pf
var1 = 'hi'
print locals()
pf.bar()
The two last lines would give the same output. So far I've tried defining bar as such:
def bar(x=locals):
print x()
def bar(x=locals()):
print x
But neither works. The first ends up being what's local to bar's namespace (which I guess is because that's when it's evaluated), and the second is as if I passed in globals (which I assume is because it's evaluated during import).
Is there a way I can have the default value of argument x of bar be all variables in the namespace which called bar?
EDIT 2018-07-29:
As has been pointed out, what was given was an XY Problem; as such, I'll give the specifics.
The module I'm putting together will allow the user to create various objects that represent different aspects of a numerical problem (e.x. various topology definitions, boundary conditions, constitutive models, ect.) and define how any given object interacts with any other object(s). The idea is for the user to import the module, define the various model entities that they need, and then call a function which will take all objects passed to it, make needed adjustments to ensure capability between them, and then write out a file that represents the entire numerical problem as a text file.
The module has a function generate that accepts each of the various types of aspects of the numerical problem. The default value for all arguments is an empty list. If a non-empty list is passed, then generate will use those instances for generating the completed numerical problem. If an argument is an empty list, then I'd like it to take in all instances in the namespace that called generate (which I will then parse out the appropriate instances for the argument).
EDIT 2018-07-29:
Sorry for any lack of understanding on my part (I'm not that strong of a programmer), but I think I might understand what you're saying with respect to an instance being declared or registered.
From my limited understanding, could this be done by creating some sort of registry dataset (like a list or dict) in the module that will be created when the module is imported, and that all module classes take this registry object in by default. During class initialization self can be appended to said dataset, and then the genereate function will take the registry as a default value for one of the arguments?
There's no way you can do what you want directly.
locals just returns the local variables in whatever namespace it's called in. As you've seen, you have access to the namespace the function is defined in at the time of definition, and you have access to the namespace of the function itself from within the function, but you don't have access to any other namespaces.
You can do what you want indirectly… but it's almost certainly a bad idea. At least this smells like an XY problem, and whatever it is you're actually trying to do, there's probably a better way to do it.
But occasionally it is necessary, so in case you have one of those cases:
The main good reason to want to know the locals of your caller is for some kind of debugging or other introspection function. And the way to do introspection is almost always through the inspect library.
In this case, what you want to inspect is the interpreter call stack. The calling function will be the first frame on the call stack behind your function's own frame.
You can get the raw stack frame:
inspect.currentframe().f_back
… or you can get a FrameInfo representing it:
inspect.stack()[1]
As explained at the top of the inspect docs, a frame object's local namespace is available as:
frame.f_locals
Note that this has all the same caveats that apply to getting your own locals with locals: what you get isn't the live namespace, but a mapping that, even if it is mutable, can't be used to modify the namespace (or, worse in 2.x, one that may or may not modify the namespace, unpredictably), and that has all cell and free variables flattened into their values rather than their cell references.
Also, see the big warning in the docs about not keeping frame objects alive unnecessarily (or calling their clear method if you need to keep a snapshot but not all of the references, but I think that only exists in 3.x).

Limitations of variables in python

I realize this may be a bit broad, and thought this was an interesting question that I haven't really seen an answer to. It may be hidden in the python documentation somewhere, but as I'm new to python haven't gone through all of it yet.
So.. are there any general rules of things that we cannot set to be variables? Everything in python is an object and we can use variables for the typical standard usage of storing strings, integers, aliasing variables, lists, calling references to classes, etc and if we're clever even something along the lines as the below that I can think of off the top of my head, wherever this may be useful
var = lambda: some_function()
storing comparison operators to clean code up such as:
var = some_value < some_value ...
So, that being said I've never come across anything that I couldn't store as a variable if I really wanted to, and was wondering if there really are any limitations?
You can't store syntactical constructs in a variable. For example, you can't do
command = break
while condition:
if other_condition:
command
or
operator = +
three = 1 operator 2
You can't really store expressions and statements as objects in Python.
Sure, you can wrap an expression in a lambda, and you can wrap a series of statements in a code object or callable, but you can't easily manipulate them. For instance, changing all instances of addition to multiplication is not readily possible.
To some extent, this can be worked around with the ast module, which provides for parsing Python code into abstract syntax trees. You can then manipulate the trees, instead of the code itself, and pass it to compile() to turn it back into a code object.
However, this is a form of indirection, compensating for a feature Python itself lacks. ast can't really compare to the anything-goes flexibility of (say) Lisp macros.
According to the Language Reference, the right hand side of an assignment statement can be an 'expression list' or a 'yield expression'. An expression list is a comma-separated list of one or more expressions. You need to follow this through several more tokens to come up with anything concrete, but ultimately you can find that an 'expression' is any number of objects (literals or variable names, or the result of applying a unary operator such as not, ~ or - to a nested expression_list) chained together by any binary operator (such as the arithmetic, comparison or bitwise operators, or logical and and or) or the ternary a if condition else b.
You can also note in other parts of the language reference that an 'expression' is exactly something you can use as an argument to a function, or as the first part (before the for) of a list comprehension or generator expression.
This is a fairly broad definition - in fact, it amounts to "anything Python resolves to an object". But it does leave out a few things - for example, you can't directly store the less-than operator < in a variable, since it isn't a valid expression by itself (it has to be between two other expressions) and you have to put it in a function that uses it instead. Similarly, most of the Python keywords aren't expressions (the exceptions are True, False and None, which are all canonical names for certain objects).
Note especially that functions are also objects, and hence the name of a function (without calling it) is a valid expression. This means that your example:
var = lambda: some_function()
can be written as:
var = some_function
By definition, a variable is something which can vary, or change. In its broadest sense, a variable is no more than a way of referring to a location in memory in your given program. Another way to think of a variable is as a container to place your information in.
Unlike popular strongly typed languages, variable declaration in Python is not required. You can place pretty much anything in a variable so long as you can come up with a name for it. Furthermore, in addition to the value of a variable in Python being capable of changing, the type often can as well.
To address your question, I would say the limitations on a variable in Python relate only to a few basic necessary attributes:
A name
A scope
A value
(Usually) a type
As a result, things like operators (+ or * for instance) cannot be stored in a variable as they do not meet these basic requirements, and in general you cannot store expressions themselves as variables (unless you're wrapping them in a lambda expression).
As mentioned by Kevin, it's also worth noting that it is possible to sort of store an operator in a variable using the operator module , however even doing so you cannot perform the kinds of manipulations that a variable is otherwise subject to as really you are just making a value assignment. An example of the operator module:
import operator
operations = {"+": operator.add,
"-": operator.sub,}
operator_variable_string= input('Give me an operand:')
operator_function = operations[operator_variable_string]
result = operator_function(8, 4)

Python: how to make a function visible throughout a program

I have two functions like the following:
def fitnesscompare(x, y):
if x.fitness>y.fitness:
return 1
elif x.fitness==y.fitness:
return 0
else: #x.fitness<y.fitness
return -1
that are used with 'sort' to sort on different attributes of class instances.
These are used from within other functions and methods in the program.
Can I make them visible everywhere rather than having to pass them to each object in which they are used?
Thanks
The best approach (to get the visibility you ask about) is to put this def statement in a module (say fit.py), import fit from any other module that needs access to items defined in this one, and use fit.fitnesscompare in any of those modules as needed.
What you ask, and what you really need, may actually be different...:
as I explained in another post earlier today, custom comparison functions are not the best way to customize sorting in Python (which is why in Python 3 they're not even allowed any more): rather, a custom key-extraction function will serve you much better (future-proof, more general, faster). I.e., instead of calling, say
somelist.sort(cmp=fit.fitnesscompare)
call
somelist.sort(key=fit.fitnessextract)
where
def fitnessextract(x):
return x.fitness
or, for really blazing speed,
import operator
somelist.sort(key=operator.attrgetter('fitness'))
Defining a function with def makes that function available within whatever scope you've defined it in. At module level, using def will make that function available to any other function inside that module.
Can you perhaps post an example of what is not working for you? The code you've posted appears to be unrelated to your actual problem.

Categories