Here's my approach to determine the number of slots in the pure function without counting those in any sub-functions. That means MapIndexed[#1^#2 &, #1] & (per @TeakeNutma's comment in @JohnMcGee's answer) will only return one slot. I do this by deleting all inner Functions before counting the slots:
Clear[slotCount]
slotCount[f_Function]:=Module[{deleteInner},
deleteInner=Replace[f,_Function:>Sequence[],{1,Infinity}];
DeleteDuplicates[Cases[deleteInner,_Slot,{1,Infinity},Heads->True]]//Length
]
Notes: Using Heads->True for Cases will count slots correctly for cases like #1[#2].
Testing on the example functions in @TeakeNutma's answer
{#,slotCount[#]}&/@{Function[{},Null],MapIndexed[#1^#2&,#]&,#1+#2&,{#1,#2,#3,##}&,#1+#4&}//Grid[#,Frame->All]&

I'm not quite sure #1 + #4 & would have 4 slots (instead of just 2). Below is a modified version of my slotCount function that will return 4:
Clear[slotCountPositionAware]
slotCountPositionAware[f_Function]:=Module[{deleteInner,slotList,maxSlot},
deleteInner=Replace[f,_Function:>Sequence[],{1,Infinity}];
slotList=DeleteDuplicates[Cases[deleteInner,_Slot,{1,Infinity},Heads->True]];
maxSlot[l_List]:=If[l=={},0,l/.Slot[x_]:>x//Max];
maxSlot[slotList]
]
{#,slotCountPositionAware[#]}&/@{Function[{},Null],MapIndexed[#1^#2&,#]&,#1+#2&,{#1,#2,#3,##}&,#1+#4&}//Grid[#,Frame->All]&

Count[f, _Slot, ∞]– m_goldberg Aug 05 '14 at 16:13#one + #two &) – Szabolcs Aug 05 '14 at 17:04GoodFuncQ[func]returns true iffunchas exactly 2 arguments, otherwise, false. – Analysis Aug 05 '14 at 19:41Checkfor error messages during application, as I suspect such tests cannot be written robustly for all possible input, at least not without unreasonable overhead. Perhaps one of the argument testing frameworks I presented here will be useful to you. – Mr.Wizard Aug 05 '14 at 20:23