STY: Changed x.__class__ to type(x)
- [ ] closes #xxxx
- [ ] tests added / passed
- [ ] passes `black pandas`
- [ ] passes `git diff upstream/master -u -- "*.py" | flake8 --diff`
- [ ] whatsnew entry

Is this supposed to make any difference in Python3 or just a stylistic thing? If so, lgtm > Is this supposed to make any difference in Python3 or just a stylistic thing? If so, lgtm

Pure stylistic change. trying to be consistent.

something that was mentioned [here](https://github.com/pandas-dev/pandas/pull/29775#discussion_r349407678). Two questions, not blockers

- Is there a meaningful difference between using `type(self)` vs `type(self).__name__`?
- Can/should we implement a code_check for this? >     * Is there a meaningful difference between using `type(self)` vs `type(self).__name__`?

The [Python docs](https://docs.python.org/3.6/library/types.html#module-types) explains this much better.

In 2 lines summary it goes like this:
* ```type(self)``` --> ```'<class self>'``` (```type``` type)
* ```type(self).__name__``` --> ```'self'``` (```str``` type)

The detailed explanation bellow:

The way I see it if you're comparing only ```type(self)``` and ```type(self).__name__```,  ```type(self)``` will return a ```type``` class, if you print the output as a string, you'll get ```<class self>```. for example:

```python
>>> my_str = 'Example'
>>> type(my_str)
<class 'str'>
>>> type(type(my_str))
<class 'type'>
```

But if you add ```.__name__``` to it, it will return a ```str``` class, and if you print it as a string it will print only the class name (as a string).
For example:

```python
>>> my_int = 1
>>> type(my_int).__name__
'int'
>>> type(type(my_int).__name__)
<class 'str'>
```

P.S
Really hope my explanation didn't confuse anyone. Mostly more confusing; I think the focus needs to be on `str(...)` and not `type(...)`.  It does seem clear though that using `__name__` should be preferred, yah? @jbrockmendel Now I'm confused lol.

```type(self)``` and ```type(self).__name__``` returns totally different things.

Can you give an example(preferably code) of what is preferred and what should not be?

Would love to correct my PR accordingly. > lgtm. can you implement a code_check for the now banned format as well? (basically grep for `self.__class__` i think would be enough

@jreback TBH no, I have no clue on to approach that (writing tests).

Plus I don't think a simple grep will do the work unfortunately. there are files like ```pandas/core/indexing.py``` with that ```self.__class__``` syntax https://github.com/pandas-dev/pandas/blob/de28255b1605a4925636f686c6279073a2abf5cd/pandas/core/indexing.py#L108

But I do think that if we ban the ```self.__class__.__name__``` we should be alright. why is this ok? ```self.__class__(self.name, self.obj)```

that should simply be ```type(self)(self.name, self.obj)``` no? > why is this ok? `self.__class__(self.name, self.obj)`
> 
> that should simply be ```type(self)(self.name, self.obj)`` no?

Gave me an error when I tried exactly what you wrote.
But please do check it yourself. I might screwed something elsewhere that has nothing to do with that error. @MomIsBestFriend pls ignore my previous comment(s), it looks like they only made things more confusing without being productive.  This PR was/is fine before I started talking.

@jreback let's hold off on a code check for the next round; the diff here is already wide-reaching. @jreback looks like ```new_self = type(self)(self.name, self.obj)``` is indeed the correct syntax replacement for ```new_self = self.__class__(self.name, self.obj) ``` (I don't know why I got an error before).
Ill push the different version later. Since this PR got too large, and I can't detect where is the error, I'm closing it.
I will push this PR in batches instead of one large PR.