Python Extension Returned Object Etiquette - python

I am writing a python extension to provide access to Solaris kstat data ( in the same spirit as the shipping perl library Sun::Solaris::Kstat ) and I have a question about conditionally returning a list or a single object. The python use case would look something like:
cpu_stats = cKstats.lookup(module='cpu_stat')
cpu_stat0 = cKstats.lookup('cpu_stat',0,'cpu_stat0')
As it's currently implemented, lookup() returns a list of all kstat objects which match. The first case would result in a list of objects ( as many as there are CPUs ) and the second call specifies a single kstat completely and would return a list containing one kstat.
My question is it poor form to return a single object when there is only one match, and a list when there are many?
Thank you for the thoughtful answer! My python-fu is weak but growing stronger due to folks like you.

"My question is it poor form to return a single object when there is only one match, and a list when there are many?"
It's poor form to return inconsistent types.
Return a consistent type: List of kstat.
Most Pythonistas don't like using type(result) to determine if it's a kstat or a list of kstats.
We'd rather check the length of the list in a simple, consistent way.
Also, if the length depends on a piece of system information, perhaps an API method could provide this metadata.
Look at DB-API PEP for advice and ideas on how to handle query-like things.

Related

How to parse the elements of a list as arguments for a method? Specifically, for Google Ads API

I'm trying to modularize a type of report from the API. This is my query for the request:
content = ['CampaignId', 'AdvertisingChannelType', ...]
report_query = (adwords.ReportQueryBuilder()
.Select(content)
.From('CAMPAIGN_PERFORMANCE_REPORT')
.During(start_date=since,end_date=until)
.Build())
However, I'm having a problem with the .Select() statement since its common usage is .Select('CampaignId', 'AdvertisingChannelType', ...) (as the list but without the brackets []) and in my query I'm parsing the arguments as a list, which of course returns an error.
My question is, how can I parse the elements of content as required? I've tried turning the list into a string but it doesn't work as all the list becomes a single element. I can't assign by hand the elements since it's number may vary (will be used for more than one client).
Any help will be appreciated. Thanks!
I'm not sure exactly if this is helpful, but maybe try looking into python maps.

Idiomatic way to to match against list of munch.munch objects?

I am using the openstack shade library to manage our openstack stacks. One task is to list all stacks owned by a user (for example to then allow for deletion of them).
The shade library call list_stacks() returns a list of munch.Munch objects, and basically I want to identify that stack object that has either an 'id' or 'name' matching some user provided input.
I came up with this code here:
def __find_stack(self, connection, stack_info):
stacks = connection.list_stacks()
for stack in stacks:
if stack_info in stack.values():
return stack
return None
But it feels clumsy, and I am wondering if there is a more idiomatic way to solve this in python? (stack_info is a simple string, either the "name" or "id", in other words: it might match this or that entry within the "dict" values of the munched stack objects)
As my comment suggests, I don't really think there is something to improve.
However, performance-wise, you could use filter to push the loop down to C level which may be beneficial if there are a lot of stacks.
Readability-wise, I don't think that you would gain much.
def __find_stack(self, connection, stack_info):
stacks = connection.list_stacks()
return list(filter(lambda stack: stack_info in stack.values(), stacks))
However this approach is not "short-circuited". Your original code stops when it finds a match, and this one will not, so in theory you will get more than one match if they exist (or an empty list in case there is no match).

How do I get a formatted list of methods from a given object?

I'm a beginner, and the answers I've found online so far for this have been too complicated to be useful, so I'm looking for an answer in vocabulary and complexity similar to this writing.
I'm using python 2.7 in ipython notebook environment, along with related modules as distributed by anaconda, and I need to learn about the library-specific objects in the course of my daily work. The case I'm using here is a pandas dataframe object but the answer must work for any object of python or of an imported module.
I want to be able to print a list of methods for the given object. Directly from my program, in a concise and readable format. Even if it's just the method names in a list by alphabetical order, that would be great. A bit more detail would be even better, an ordering based on what it does is fine, but I'd like the output to look like a table, one row per method, and not big blocks of text. What i've tried is below, and it fails for me because it's unreadable. It puts copies of my data between each line, and it has no formatting.
(I love stackoverflow. I aspire to have enough points someday to upvote all your wonderful answers.)
import pandas
import inspect
data_json = """{"0":{"comment":"I won\'t go to school"}, "1":{"note":"Then you must stay in bed"}}"""
data_df = pandas.io.json.read_json(data_json, typ='frame',
dtype=True, convert_axes=True,
convert_dates=True, keep_default_dates=True,
numpy=False, precise_float=False,
date_unit=None)
inspect.getmembers(data_df, inspect.ismethod)
Thanks,
- Sharon
Create an object of type str:
name = "Fido"
List all its attributes (there are no “methods” in Python) in alphabetical order:
for attr in sorted(dir(name)):
print attr
Get more information about the lower (function) attribute:
print(name.lower.__doc__)
In an interactive session, you can also use the more convenient
help(name.lower)
function.

array vs hash key search

So I'm a longtime perl scripter who's been getting used to python since I changed jobs a few months back. Often in perl, if I had a list of values that I needed to check a variable against (simply to see if there is a match in the list), I found it easier to generate hashes to check against, instead of putting the values into an array, like so:
$checklist{'val1'} = undef;
$checklist{'val2'} = undef;
...
if (exists $checklist{$value_to_check}) { ... }
Obviously this wastes some memory because of the need for a useless right-hand value, but IMO is more efficients and easier to code than to loop through an array.
Now in python, the code for this is exactly the same no matter if you're searching an list or a dictionary:
if value_to_check in checklist_which_can_be_list_or_dict:
<code>
So my real question here is: in perl, the hash method was preferred for speed of processing vs. iterating through an array, but is this true in python? Given the code is the same, I'm wondering if python does list iteration better? Should I still use the dictionary method for larger lists?
Dictionaries are hashes. An in test on a list has to walk through every element to check it against, while an in test on a dictionary uses hashing to see if the key exists. Python just doesn't make you explicitly loop through the list.
Python also has a set datatype. It's basically a hash/dictionary without the right-hand values. If what you want is to be able to build up a collection of things, then test whether something is already in that collection, and you don't care about the order of the things or whether a thing is in the collection multiple times, then a set is exactly what you want!

Python: Why Lists do not have a find method?

I was trying to write an answer to this question and was quite surprised to find out that there is no find method for lists, lists have only the index method (strings have find and index).
Can anyone tell me the rationale behind that?
Why strings have both?
I don't know why or maybe is buried in some PEP somewhere, but i do know 2 very basic "find" method for lists, and they are array.index() and the in operator. You can always make use of these 2 to find your items. (Also, re module, etc)
I think the rationale for not having separate 'find' and 'index' methods is they're not different enough. Both would return the same thing in the case the sought item exists in the list (this is true of the two string methods); they differ in case the sought item is not in the list/string; however you can trivially build either one of find/index from the other. If you're coming from other languages, it may seem bad manners to raise and catch exceptions for a non-error condition that you could easily test for, but in Python, it's often considered more pythonic to shoot first and ask questions later, er, to use exception handling instead of tests like this (example: Better to 'try' something and catch the exception or test if its possible first to avoid an exception?).
I don't think it's a good idea to build 'find' out of 'index' and 'in', like
if foo in my_list:
foo_index = my_list.index(foo)
else:
foo_index = -1 # or do whatever else you want
because both in and index will require an O(n) pass over the list.
Better to build 'find' out of 'index' and try/catch, like:
try:
foo_index = my_list.index(foo)
catch ValueError:
foo_index = -1 # or do whatever else you want
Now, as to why list was built this way (with only index), and string was built the other way (with separate index and find)... I can't say.
The "find" method for lists is index.
I do consider the inconsistency between string.find and list.index to be unfortunate, both in name and behavior: string.find returns -1 when no match is found, where list.index raises ValueError. This could have been designed more consistently. The only irreconcilable difference between these operations is that string.find searches for a string of items, where list.index searches for exactly one item (which, alone, doesn't justify using different names).

Categories