Python和C#对比学习系列——构造函数及析构函数的对比

以及拓展单例的分析

Posted by JohnWayne on April 1, 2022

Python和C#语法各有特色,笔者当前从自研引擎全面转向U3d的过程中,遇到很多C#和Python不一样的地方和概念,计划出一个对比系列,记录学习,也供python,C#双修党参考交流。


Python的构造和析构

# -*- coding: utf-8 -*- 
class PyCmpCSharp1:
    '''Python的构造和析构'''
    #构造方法     
    def __init__(self, **kwargs):
        name = kwargs.get('name', '')
        age = kwargs.get('age', 0)
        if name:
            print("调用带参数的构造方法")
        else:
            print("调用构造方法")
        print("name:" + str(name))
        print("age:" + str(age))
    #析构方法     
    def __del__(self):
        print("销毁了")
        
obj = PyCmpCSharp1()
obj = PyCmpCSharp1(name='张三', age=18)
>>>
调用构造方法
name:
age:0
调用带参数的构造方法
name:张三
age:18
销毁了
销毁了

注意,python不支持重载,__init__只能写一个,但可以用args,*kwargs来实现可变参数类型、可变参数个数。

下面来看看C#的

using System;
 
public class PyCmpCSharp1
{
    public string name;
    public int age;
    //构造方法
    public PyCmpCSharp1()
    {
        Console.WriteLine("调用构造方法");
    }
    //构造方法
    public PyCmpCSharp1(string name, int age)
    {
        Console.WriteLine("调用带参数的构造方法");
        Console.WriteLine("name:"+name);
        Console.WriteLine("age:"+age.ToString());
    }
    
    //析构方法
    ~PyCmpCSharp1()
    {
        Console.WriteLine("销毁了");
    }
    
}

public class Test
{
    public static void Main()
	{
	    PyCmpCSharp1 obj_1 = new PyCmpCSharp1();
	    PyCmpCSharp1 obj_2 = new PyCmpCSharp1("张三", 18);
	}
}
>>>
调用构造方法
调用带参数的构造方法
name:张三
age:18
销毁了
销毁了

C# 静态构造函数

using System;
 
public class PyCmpCSharp1
{
    public string name;
    public int age;
    //静态构造方法
    static PyCmpCSharp1()
    {
        Console.WriteLine("调用构造方法");
    }
}

public class Test
{
    public static void Main()
	{
	    PyCmpCSharp1 obj_1 = new PyCmpCSharp1();
	    PyCmpCSharp1 obj_2 = new PyCmpCSharp1();
	}
}

>>>
调用构造方法

无论实例数量,只执行一次,且不能带参数

Python 静态构造函数,加@staticmethod

# -*- coding: utf-8 -*-
class PyCmpCSharp1:
    '''这是一个学习Python定义的第一个类'''
    #静态构造方法
    @staticmethod
    def __init__():
        print("调用带参数的构造方法")
        
obj = PyCmpCSharp1()
obj2 = PyCmpCSharp1()
>>>
调用带参数的构造方法
调用带参数的构造方法

不影响执行次数 __init__换成__new__也不影响

总结区别

1.python不支持重载;

2.C#析构函数只能被自动调用,python可以手动调用__del__()。

3.python不支持只执行一次的静态构造函数。python需要通过单例模式来达到类似的效果。 但是单例和静态函数还是有区别的 https://www.codeproject.com/Articles/90896/Singletons-in-C-Static-Constructor-vs-Static-Initi

###再拓展一下python和C#的单例

class Singleton(object):
    def __new__(cls, *args, **kwargs):
        # 关键在这里,每一次实例化时,我们都只会返回这同一个instance对象 
        if not hasattr(cls, 'instance'):
            cls.instance = super(Singleton, cls).__new__(cls)
        return cls.instance

class MyClass(Singleton):            
    def __init__(self, attr):
        self.attr1 = attr
        

object1 = MyClass(10)
object2 = MyClass(20)

print(object1.attr1, object2.attr1)
print(id(object1), id(object2))
>>>
20 20
140049636917008 140049636917008
using System;

public sealed class Singleton
{
    private static Singleton _instance = null;

    private Singleton()
    {

    }

    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new Singleton();
            }
            return _instance;
        }
    }
    
    public void show(){
        Console.WriteLine(_instance.GetHashCode());
    }
}
public class Test
{
	public static void Main()
	{
		Singleton single1 = Singleton.Instance;
		single1.show();
		Singleton single2 = Singleton.Instance;
		single2.show();
	}
}
>>>
994246326
994246326

以上都是没有考虑线程安全的情况,考虑后需要加锁,更加复杂。

作者 [张巍]

2022 年 04月 01日