Q:

Is there a way to show the type of every column in Python?

I use dtype to show the types of the columns, but most of the types will appear as object and you need to check it individually by using the type() method to know, for example, if it is an str actully.
Is there a better way to get it str or numpy.int64 from the first place and not having to check them individually?
df_08.dtypes

>>>model                    object
displ                   float64
cyl                      object
trans                    object
drive                    object
fuel                     object
veh_class                object
air_pollution_score      object
city_mpg                 object
hwy_mpg                  object
cmb_mpg                  object
greenhouse_gas_score     object
smartway                 object
dtype: object

type(df_18['air_pollution_score'][1])
>>> numpy.int64

and there is no nan values in the dataframe.

A:

The problem is likely that you have empty values in these "object" columns. Pandas stores empty values as 'nan' which is a float. If that's intermixed with other types like ints or strings, then the whole column is marked as having a dtype of "object" (it's unknown because no other single dtype applies to the whole column).
To check this, look at the output of:
{type(val) for val in df_18['air_pollution_score']}

You could get the dtype of all non-null objects using the following trick:
{col: df_18.loc[~pd.isnull(df_18[col]), col].dtype for col in df_18}

If that still doesn't work, you can just check all the types individually:
{col: set(df.loc[~pd.isnull(df[col]), col].apply(type).drop_duplicates()) for col in df}

