Default arguments

Recall in the earlier Intersections section that we passed the u=True argument to a.intersect():

>>> import pybedtools
>>> a = pybedtools.example_bedtool('a.bed')
>>> b = pybedtools.example_bedtool('b.bed')
>>> a_with_b = a.intersect(b, u=True)

Let’s do the same thing but use different variable names for the BedTool objects so that the next section is less confusing:

>>> import pybedtools
>>> exons = pybedtools.example_bedtool('a.bed')
>>> snps = pybedtools.example_bedtool('b.bed')
>>> exons_with_snps = exons.intersect(snps, u=True)

While we’re on the subject of arguments, note that we didn’t have to specify -a or -b arguments, like you would need if calling intersectBed from the command line. In other words, since exons refers to the file a.bed and snps refers to the file b.bed, the following line:

>>> exons_with_snps = exons.intersect(snps, u=True)

is equivalent to the command line usage of:

$ intersectBed -a a.bed -b b.bed -u > tmpfile

But we didn’t have to explicitly pass the argument for -a because BedTool objects make some assumptions for convenience.

We’re calling a method on the BedTool object exons, so pybedtools assumes that the file exons points to (stored in the attribute exons.fn) is the one we want to use as input. So by default, we don’t need to explicitly give the keyword argument a=exons.fn because the exons.intersect() method does so automatically.

We’re also calling a method that takes a second bed file as input – other such methods include BedTool.subtract() and BedTool.closest(), and others. For these methods, in addition to assuming -a is taken care of by the BedTool.fn attribute, pybedtools also assumes the first unnamed argument to these methods are the second file you want to operate on (and if you pass a BedTool, it’ll automatically use the file in the fn attribute of that BedTool).

An example may help to illustrate: these different ways of calling BedTool.intersect() all have the same results, with the first version being the most compact (and probably most convenient):

>>> # these all have identical results
>>> x1 = exons.intersect(snps)
>>> x2 = exons.intersect(a=exons.fn, b=snps.fn)
>>> x3 = exons.intersect(b=snps.fn)
>>> x4 = exons.intersect(snps, a=exons.fn)
>>> x1 == x2 == x3 == x4

Note that a.intersect(a=a.fn, b) is not a valid Python expression, since non-keyword arguments must come before keyword arguments, but a.intersect(b, a=a.fn) works fine.

If you’re ever unsure, the docstring for these methods indicates which, if any, arguments are used as default. For example, in the BedTool.intersect() help, it says:

For convenience, the file or stream this BedTool points to is implicitly
passed as the -a argument to intersectBed

OK, enough about arguments for now, but you can read more about them in Principle 2: Names and arguments are as similar as possible to BEDTools, Principle 4: Sensible default args and Principal 5: Other arguments have no defaults.