1.Python函数基础:一个例子,带余除法

def dwr(a, b):
    if b == 0:
        return "不能除以0"
    else:
        return a//b,a%b
print(dwr(5, 0),dwr(5,2),sep="\n")

不能除以0
(2, 1)

值得注意的是,与java的不同之处在于,python的函数调用要写在定义之后,否则会报错。

2.全局变量与局部变量

在java中:

(1)先不管运行结果,研究实例与静态这个问题

①实例变量、实例方法版:

import java.util.Arrays;

public class Main {
    int a = 100;

    public static void main(String[] args) {
        int b[] = {100};
        int c = 100;
        Main t = new Main();
        t.fun1(b);
        t.fun1(c);
        System.out.println(t.a);
        System.out.println(Arrays.toString(b));
        System.out.println(c);
    }

    public void fun1(int[] a) {
        a[0] = 200;
        this.a = 200;
    }

    public void fun1(int c) {
        c = 200;
    }
}

②静态变量、静态方法版:

/**
 * fileName: Main3.java
 * author: hexh
 * creationTime: 2023-08-16 20:50
 * software: IntelliJ IDEA
 */
//静态变量、静态方法

import java.util.Arrays;

public class Main3 {
    static int a = 100;

    public static void main(String[] args) {
        int b[] = {100};
        int c = 100;
        fun1(b);
        fun1(c);
        System.out.println(a);
        System.out.println(Arrays.toString(b));
        System.out.println(c);
    }

    public static void fun1(int[] a) {
        a[0] = 200;
        Main3.a = 200;
        Main3 t = new Main3();
        t.a = 200;
        //等价
    }

    public static void fun1(int c) {
        c = 200;
    }
}

③实例变量、静态方法版:

静态方法不能直接访问实例变量,但是只能间接访问

import java.util.Arrays;

//实例变量、静态方法
public class Main {
    int a = 100;

    public static void main(String[] args) {
        int b[] = {100};
        int c = 100;
        Main t = new Main();
        t.fun1(b, t); //静态方法可以使用实例对象调用
        Main.fun1(b, t);//也可使用类名调用
        fun1(b, t); //还可以直接调用
        t.fun1(c);
        System.out.println(t.a);  //实例变量只能使用实例对象调用
        System.out.println(Arrays.toString(b));
        System.out.println(c);
    }

    public static void fun1(int[] a, Main t) {
        a[0] = 200;
        t.a = 200;  //实例变量只能通过类的实例对象访问
    }

    public static void fun1(int c) {
        c = 200;
    }
}

④静态变量、实例方法版:

import java.util.Arrays;

public class Main {
    static int a = 100;

    public static void main(String[] args) {
        int b[] = {100};
        int c = 100;
        Main t = new Main();
        t.fun1(b); //实例方法只能使用实例对象调用
        t.fun1(c);
        System.out.println(t.a);  //静态变量可以使用实例对象调用
        System.out.println(Main.a);  //静态变量可以使用实例对象调用(等价),也就是说所有实例共用这一个a
        System.out.println(a);  //还可以直接调用
        System.out.println(Arrays.toString(b));
        System.out.println(c);
    }

    public void fun1(int[] a) {
        a[0] = 200;
        Main.a = 200;
        this.a = 200;  //等价
    }

    public void fun1(int c) {
        c = 200;
    }
}

小结

变量:

静态变量,整个类共用的变量,可以用类的实例对象访问、类名访问、直接访问。

实例变量,一个实例特有的变量,只能用类的实例对象访问

方法:

静态方法,与实例无关的方法(即这个函数只依赖于方法传入的参数),可以用类的实例对象调用(但与这个实例对象毫无关系哦)、类名调用、直接调用

静态方法中无法直接访问实例变量,因为静态方法根本不知道你要访问哪一个实例对象,解决办法可以是在形参里设置传入实例。

静态方法中访问静态变量,可以用上面说的三点来访问,但局部变量中已经存在一个同名变量时,就不能使用直接访问法了,得使用另外两种方法。这一点就像是Python中global的作用了。

实例方法,对一个实例来说的方法(即这个函数除了知道当前方法传入的参数,还知道一个隐藏知识:当前实例对象),只能用类的实例对象调用。

实例方法中访问当前实例对象的实例变量(获取隐藏知识):this关键字获取当前实例对象,然后用实例对象访问

实例方法中访问静态对象,同上,三种,同名时只有两种了。

(2)观察运行结果,讨论函数与数据类型的关系

200
[200]
100

可以看到a,b,c中a,b在函数的作用后,值发生了变化,而c没有。

这是因为a是类Main的属性,b是数组,是引用数据类型,标识符里存储的是地址,传入函数的也是地址,在函数内对地址操作,跳出函数后,在去地址里取值,所以变了。

而c是基本数据类型,标识符下存的就是值,传入函数时直接传的值,任你函数怎么搞,原来的值始终不变。


在Python中:

a=100
b=[100]
c=100

def fun1(c):  #相当于传入一个东西
    c=200     #新定义一个c
    a=200     #新定义一个a
    b=[200]   #新定义一个b

def fun2(b):
    b=[200]   #同上

def fun3():
    b[0]=200

def fun4():
    global a,b,c
    c = 200
    a = 200
    b = [200]

fun1(c)
print(a,b,c)
fun2(b)
print(a,b,c)
fun3()
print(a,b,c)
fun4()
print(a,b,c)

100 [100] 100
100 [100] 100
100 [200] 100
200 [200] 200

思考:能否写一个函数,修改传入参数的值?

a=100
def fun1(v):
    v=0
fun1(a)
print(a)

100

感谢CSDN上kongsuhongbaby提供的一种方案:

from varname import nameof

a = 100


def func(var, new_value):
    if var in globals():
        globals()[var] = new_value


func(nameof(a), 0)
print(a)

0