BUG/ENH: MI.get_level_values and MI.set_levels get confused if level name happens to be int
While working on a PR, find out a confusion when level names are integer/None, e.g.

```python
>>> mi = pd.MultiIndex.from_frame(pd.DataFrame([[0.5,1],[0.5,0], [0.6, 0], [0.6,1]]), names=[None, 0])
>>> mi
MultiIndex([(0.5, 1),
            (0.5, 0),
            (0.6, 0),
            (0.6, 1)],
           )
>>> mi.get_level_values(0)
Int64Index([1, 0, 0, 1], dtype='int64', name=0)
>>> mi.set_levels([0.2, 0.3], level=0)
MultiIndex([(0.5, 0.3),
            (0.5, 0.2),
            (0.6, 0.2),
            (0.6, 0.3)],
           )
```
Pandas has quite big tolerrance of names setting, however, if names is set by int, and happens to be valid position, then using `set_levels` to change level value could be confusing, and also using level name to only change level values for `None` becomes difficult, because by default, `None` should be used to set values for all levels, the same happens if names is `[0, 1]`, e.g.

```python
>>> mi = pd.MultiIndex.from_frame(pd.DataFrame([[0.5,1],[0.5,0], [0.6, 0], [0.6,1]]), names=[1, 0])
>>> mi
MultiIndex([(0.5, 1),
            (0.5, 0),
            (0.6, 0),
            (0.6, 1)],
           names=[1, 0])
>>> mi.set_levels([0.2,0.3], level=0)
MultiIndex([(0.5, 0.3),
            (0.5, 0.2),
            (0.6, 0.2),
            (0.6, 0.3)],
           )
```

And yes, these are really corner cases, but might be nice to resolve to let users explicitly set/get level values! I am not sure what is the best way to figure it out, I am thinking of something like: `get_level_values_by_name(0)` or `get_level_values_by_loc(0)`, or have an argument in `get_level_values`, e.g. `get_level_values(0, by_name=True)`, default is `False` which uses loc to get values.

All feedbacks are very welcome, if there is kind of consensus, i would like to work on it!
@jreback @WillAyd @TomAugspurger @jorisvandenbossche 
