# TODO py中数据类型分为两种:
#     1.可变数据类型 :列表list;字典dict
#     2.不可变数据类型:整数int,小数float,字符串str,元祖tuple

# TODO py中字典的key不能是不可变类型
# TODO 不可变数据类型进行+=运算会更换地址值,就是重新指向了一个内存中的数据
# TODO 可变参数进行+=运算相当于调用extend(翻译:扩展)方法,不会更改地址值,会更改list,或者dict的内容

# TODO 全局变量命名规则一般为g_methodname或者gl_methonname,前面加上g_或者gl_
# TODO 在函数内部py中默认不允许修改全局变量,若要修改需要声明
gl_num = 1


def edit_num():
    global gl_num
    gl_num = 2
    print(gl_num)


edit_num()
print(gl_num)


# TODO 若要修改全局变量需要在函数内部用global声明这个变量是个全局变量
# TODO 将全局变量传入函数内,修改权局变量还可以使用全局变量自己的方法,修改全局变量
# TODO 将全局变量传入函数内,从新对全局变量进行赋值,不会改变全局变量,py会认为你创建了一个重名的参数名
# TODO 总而言之全局变量不会修改地址值的指向

# TODO py返回多个参数是时可返回一个元祖类型的参数,此元祖的括号可以省略,
# TODO 接收的时候用两个变量名接收即可

def result_tuple():
    """返回元祖的方法"""
    name_str = "小明"
    age_int = 15
    # 返回一个元祖,省略括号
    # return (name,age)
    return name_str, age_int


# 调用方法返回两个参数
name, age = result_tuple();

# TODO 利用返回的元祖可以省略括号的思想,可以衍生出键将两个值互换的方法
# TODO 两个值互换java中有两种解决方法
# 1.利用临时变量,将一个值赋值给临时变量,实现两个值的互换
a = 1
b = 2
# 互换ab的值
temp = a
a = b
b = temp

# 2.利用两个值的和,进行互换(适合数字类型)
a = 1
b = 2
# 互换ab的值
a = a + b
b = a - b
a = a - b

# 3.py独有的方法,利用元祖作为返回值的思想
a = 1
b = 2
# 互换ab的值
a, b = b, a  # a, b = (b, a)


# TODO 缺省参数的使用,缺省参数一定放在末尾,多个缺省参数,再传参是指定缺省参数的名字
# java中不支持缺省参数
def ages_method(name1, sex="男生", higth=180):
    """传入的sex默认为男生"""
    print("%s是一个%s,身高%d" % (name1, sex, higth))


ages_method("小明", higth=192)
ages_method("小妹", sex="女生")


# TODO 传入数量不确定的参数
# TODO 在形参前加上*相当于tuple,加上**相当于dict
# TODO 传入的参数是tuple建议形参名为*args,dict建议形参名为**kwargs(kw=keyword)


def args_list_dict(name2, *ages, **kwargs):
    """传入不确定参数个数"""
    print(name2)
    print(ages)
    print(kwargs)


# 传入的参数自动封装成tuple,dict
args_list_dict("dd", 1, 2, 3, 5, 4, 5, name="小明")


args_list = [1, 2, 3, 5, 1, 5, 4]
kwargs_dict = {"name": "小明",
               "age": 48}
# 传入的一个元祖tuple和字典dict前面加上*,**可以自动拆包
args_list_dict("小姑娘", *args_list, **kwargs_dict)