关于python的实例方法问题?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于python的实例方法问题?相关的知识,希望对你有一定的参考价值。
我定义了一个实例方法 "__init__" 下面这段代码是正常的 那为啥把“__init__”改成“init”就不能被实例对象调用了 为啥呀?不加下划线就不是实例方法了嘛?
class Student():
def __init__(self,name,age):
self.name=name
self.age=age
std=Student(name=input('请输入名字'),age=input('请输入年龄'))
print('姓名:'+std.name+' 年龄:'+std.age)
题主你好,
python中创建新实例的时候, 如果相应的类中定义了__init__()方法的话, 会自动调用这个方法. 你可能认为名称"init"和"__init__"差不多, 但计算机其实是个很笨的东西, 它会完全按照设计去执行. 也就是说,在设计的时候就已经定死了, 默认情况下, 创建新实例的时候, 会自动调用类中定义的__init__()方法, 只要你的方法名和__init__有一点不一样也不行.
下图是我在官网上找的关于__init__()调用的简单说明:
高亮部分说的大概意思就是上面讲的,如果相应类中定义了__init__()方法,则在创建该类实例的时候会自动调用里面定义的__init__()方法.
-----
希望可以帮到题主, 欢迎追问.
python 构造函数__init__() 和 实例属性、实例方法
一、创建对象,我们需要定义构造函数__init__()方法。构造方法用于执行"实例对象的初始化工作",即对象创建后,初始化当前对象的属性,无返回值。
__init__()要点如下:
1.名称固定,必须为__init__()
2.第一个参数固定,必须为self。self指的就是刚刚创建好的示例对象。
3.构造函数通常用来初始化示例属性,如下代码就是初始化示例属性:
4.通过类名(参数列表),来调用构造函数,调用后,将创建好的对象返回给相应的变量。
5.__init__()方法:初始化创建好的对象,初始化指的是:"给实例属性赋值"
6.__new__()方法:用于创建对象,但我们一般无需定义该方法。
Python单例模式
本篇主要介绍一下关于Python的单例模式,即让一个类对象有且只有一个实例化对象。
一、使用__new__方法(基类)
要实现单例模式,即为了让一个类只能实例化一个实例,那么我们可以去想:既然限制创建实例,那么我们可以修改其创建实例的根源即可,那就是父类__new__方法。
注意:不能使用自身的__new__()方法,应为自身这个类去进行实例化,是调用父类的__new__方法,若调用自身的__new__方法,那不就死循环了么,可以参考我的另外一篇博客:python类的__new__()。
class SingleTon(object): def __new__(cls, *args, **kwargs): if not hasattr(cls, \'_instance\'): cls._instance = super().__new__(cls, *args, **kwargs) # return super().__new__(cls, *args, **kwargs) return cls._instance class Foo(SingleTon): pass if __name__ == \'__main__\': f1 = Foo() f2 = Foo() print(\'f1的id:\',id(f1)) print(\'f2的id:\',id(f2)) # f1的id: 2151027475064 # f2的id: 2151027475064
注释:通过修改父类的__new__方法,去干涉子类的实例化创建实例,实现只能一个类只能有一个实例的效果。
二、使用闭包的形式
无论怎么实现,均为了让一个类只有一个实例对象,那么我们可以当类创建一个实例,我们就把使用一个变量把该实例记录下来,若该变量已经有实例了,便可把该变量返回即可,不让其进行创建新的实例。
def singleton(cls, *args, **kwargs): instances = None def get_instance(*args, **kwargs): nonlocal instances if instances is None: instances = cls(*args, **kwargs) return instances return get_instance @singleton class Bar(object): def __init__(self,name): self.name = name if __name__ == \'__main__\': b1 = Bar(\'alex\') b2 = Bar(\'hello\') print(b1.name) print(b2.name)
注:为了实现单例模式,可以在类创建实例的时候对其进行限制,即通过判断该类是否已经创建了实例,若没有进行过实例化,则我们让其进行实例化,反之,返回原有对象即可。
三、使用元类的方式
首先我们需要明确的是,当我们使用元类时:
1、类由type创建,创建类时,type的__init__方法自动执行,类() --》执行type的 __call__方法(类的__new__方法,类的__init__方法)。
2、对象由类创建,创建对象时,类的__init__方法自动执行,对象() -- 》执行类的 __call__ 方法。
那么我们可以思考:
当我们调用 类() 时不就是一个实例化的过程吗,就自动回执行 type中的call方法,所以我们需要去实现单例模式,只需要在call方法中对其进行限制是不是就可以达到我们想要的效果呢?试一试
class SingleTonType(type): def __init__(self,*args, **kwargs): super().__init__(*args, **kwargs) def __call__(cls, *args, **kwargs): _instance = None # 设置一个变量,用来存储是否创建实例 print(\'cls:\',cls) if _instance is None: obj = cls.__new__(cls,*args, **kwargs) # 会一直找到能创建实例的父类,创建实例 cls.__init__(obj, *args, **kwargs) # 构造方法去丰富该实例 cls._instance = obj # 并将变量修改的创建的实例 return _instance class Foo(metaclass=SingleTonType): def __init__(self,name): self.name = name if __name__ == \'__main__\': obj1 = Foo(\'hello\') # 会调用type类(SingleTonType)中的call方法 obj2 = Foo(\'world\')
执行结果:
cls: <class \'__main__.Foo\'> cls: <class \'__main__.Foo\'> 1841145040 1841145040
是不是达到我们实现 -- 一个类只拥有一个实例对象的效果了呢?
总结:其实实现单例模式,只需要在类进行实例化的时候,对其进行限制即可。比如在类进行实例化时,会调用父类的__new__方法,若使用元类,会调用call()方法,那么我们只需要在这两个方法中对其加以限制即可。
使用修饰器闭包的利用的也是同样的原理。
以上是关于关于python的实例方法问题?的主要内容,如果未能解决你的问题,请参考以下文章