Character Creation in Text Adventure; Proper use of Main and Global Values?
There is a way to pass the attribute name which you want to change, you can use setattr:

def change_stat(self, stat_to_change, new_number):
    setattr(self, stat_to_change, new_number)


However, there is no difference to what would happen if you just say self.strength = 10 instead of self.change_stat("strength", 10).

Regarding the need for global for the player character, there isn't. Just return the chosen class from the character_select function:

def character_select():
    barbarian = Character("Barbarian", 20, 10, 10)
    archer = Character("Archer", 10, 20, 10)
    wizard = Character("Wizard", 10, 10, 20)

    print("Welcome to TEST TEXT ADVENTURE RPG. Choose a character!")
    print("(A): " + barbarian.print_stats())
    print("(B): " + archer.print_stats())
    print("(C): " + wizard.print_stats())

    while True:
        user_answer = input().upper()
        if user_answer == "A":
            return barbarian
        elif user_answer == "B":
            return archer
        elif user_answer == "C":
            return wizard
        else:
            print("Invalid input! Try again.")


You could make it even nicer if you used a dictionary:

from collections import OrderedDict

def character_select():
    classes = OrderedDict([("A", Character("Barbarian", 20, 10, 10)),
                           ("B", Character("Archer", 10, 20, 10)),
                           ("C", Character("Wizard", 10, 10, 20))])

    print("Welcome to TEST TEXT ADVENTURE RPG. Choose a character!")
    for key, cls in classes.items():
        print("({}): {}".format(key, cls.print_stats()))

    while True:
        user_answer = input().upper()
        try:
            return classes[user_answer]
        except KeyError:
            print("Invalid input! Try again.")


You can then use it like this in your main function:

def main():
    player_class = character_select()
    print(player_class.print_stats())


You should probably rename your Character.print_stats function. Right now it sounds like it would actually print the stats, but it just returns them. So I would make your class like this:

class Character:
    def __init__(self, class_name, strength, dexterity, intelligence):
        self.class_name = class_name
        self.strength = strength
        self.dexterity = dexterity
        self.intelligence = intelligence
        self.health = strength*10

    def __str__(self):
        return "{self.class_name} " \
               "Health: {self.health} " \
               "Strength: {self.strength} " \
               "Dexterity: {self.dexterity} " \
               "Intelligence: {self.intelligence}".format(self=self)


If you are using Python 3.6, you can use f"{self.class_name} ..." instead of "{self.class_name} ...".format(self=self), which uses f-strings.

Because I named the function __str__, you can now do:

barbarian = Character("Barbarian", 20, 10, 10)
print(barbarian)
# Barbarian Health: 200 Strength: 20 Dexterity: 10 Intelligence: 10


And the loop in character_select becomes this, because str.format automatically calls str on its arguments, which will then invoke the Character.__str__ function:

for key, cls in classes.items():
    print("({}): {}".format(key, cls))


__str__ is one of the magic (or dunder) methods, which can give your class features so it acts like built-in classes. Have a look at this nice guide for a list and explanation of all of them.

Finally, you should add a if __name__ == "__main__": guard to allow importing your functions from other scripts:

if __name__ == "__main__":
    main()