类与实例python
类是对象的定义,而实例是"真正的实物",它存放了类中所定义的对象的具体信息。程序员
类、属性和方法命名规范安全
类名一般由大写字母打头。这是标准惯例,能够帮助你识别类,特别是在实例化过程当中(有时看起来像函数调用)。还有,数据属性(变量或常量)听起来应当是数据值的名字,方法名应当指出对应对象或值的行为。ssh
另外一种表达方式是:数据值应该使用名词做为名字,方法使用谓词(动词加对象)。数据项是操做的对象、方法应当代表程序员想要在对象进行什么操做。函数
在定义的类中,大体遵循这样的方针,数据值像 “name”, “phone” 和 “email”,行为如 “updatePhone”,“updateEmail”。这就是常说的 “混合记法(mixedCase)” 或 “骆驼记法(camelCase)”。Python 规范推荐使用骆驼记法的下划线方式,好比, “update_phone”,“update_email”。类也要细致命名,像 “AddrBookEntry”, “RepairShop” 等等就是很好的名字。学习
class AddrBookEntry(object): def __init__(self, name, phone, email): self.name = name self.phone = phone self.email = email def update_phone(self, phone): self.phone = phone def update_email(self. email): self.email = email
新式类与旧式类翻译
新式类和经典类声明的最大不一样在于,全部新式类必须继承至少一个父类。若是没有可继承的类,则可继承 object 类。object 是“全部类之母” ,它位于全部类继承结构的最上层。若是没有直接或间接的子类化一个对象,那么就定义了一个经典类。即若是没有指定一个父类,或者若是所子类化的基本类没有父类,这样就是建立了一个经典类。code
在 Python3 中定义的类,默认就是新式类,而在 Python2 中要定义一个新式类则必须继承 object 或者继承一个新式类。
self 变量orm
类的方法与普通的函数只有一个特别的区别,即它们必须有一个额外的第一个参数名称,可是在调用这个方法的时候你没必要为这个参数赋值,Python 会提供这个值。这个特别的变量指对象自己,按照惯例它的名称是 self。虽然能够给这个参数任何名称,可是强烈建议使用 self 这个名称,其余名称都是不同意使用的。
__init__()
方法视频
__init__()
相似于类构造器,但实际上并非一个构造器。Python 建立实例后,在实例化过程当中,调用 __init__()
方法,当一个类被实例化时,就能够定义额外的行为,好比,设定初始值或者运行一些初步诊断代码,这主要是在实例被建立后,实例化调用返回这个实例以前,去执行某些特定的任务或设置。
绑定及非绑定方法
在 Python 中,访问类的方法能够经过实例也能够经过类来直接访问。可是 Python 严格要求,没有实例,方法是不能被调用的。这种限制即 Python 所描述的绑定概念(binding),在此,方法必须绑定(到一个实例)才能直接被调用。非绑定的方法可能能够被调用,但实例对象必定要明确给出,才能确保调用成功。然而,不论是否绑定,方法都是它所在的类的固有属性,即便它们几乎老是经过实例来调用的。在 Python 中的类方法也是一种对象。能够简单的理解就是,经过类直接访问的方法称为“未绑定的方法”,而经过实例访问的方法称为“绑定的方法”:
经过类来引用方法返回一个未绑定方法对象。要调用它,你必须显示地提供一个实例做为第一个参数。
经过实例访问方法返回一个绑定的方法对象。Python 自动地给方法绑定一个实例,因此咱们调用它时不用再传一个实例参数。
示例:
''' 遇到问题没人解答?小编建立了一个Python学习交流QQ群:778463939 寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书! ''' class Test: def func(self, message): print message object1 = Test() x = object1.func x("绑定方法对象,实例是隐藏的") t = Test.func t(object1, "未绑定方法对象,须要传递一个实例") # t("未绑定方法对象,须要传递一个实例") # 错误的调用
类属性与实例属性
类属性仅是与类相关的数据值,和实例属性不一样,类属性和实例无关。这些值像静态成员那样被引用,即便在屡次实例化中调用类,它们的值都保持不变。无论如何,静态成员不会由于实例而改变它们的值,除非实例中显式改变它们的值。 实例属性与类属性的比较,相似于自动变量和静态变量,但这只是笼统的类推。在你对自动变量和静态变量还不是很熟的状况下,不要深究这些。
类和实例都是名字空间。类是类属性的名字空间,实例则是实例属性的。
可采用类来访问类属性,若是实例没有同名的属性的话,也能够用实例来访问。
私有化
Python并不直接支持私有方式,而要靠程序员本身把握在外部进行特性修改的时机。
为了让方法或者特性变为私有(从外部没法访问),只要在它的名字前面加上双下划线便可。由双下划线 __ 开始的属性在运行时被“混淆”,因此直接访问是不容许的。
实际上,在 Python 带有双下划线的属性或方法并不是正真意义上的私有,它们仍然能够被访问。在类的内部定义中,全部以双下划线开始的名字都被“翻译”成前面加上单下划线和类名的形式:
>>> class TestObj(object): ... __war = "world" ... ... def __init__(self): ... self.__har = "hello" ... ... def __foo(self): ... print(self.__har + self.__war) ... ... ... >>> t = TestObj() >>> dir(t) ['_TestObj__foo', '_TestObj__har', '_TestObj__war', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getat tribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__ ', '__sizeof__', '__str__', '__subclasshook__', '__weakref__'] >>> t.__war Traceback (most recent call last): File "<input>", line 1, in <module> t.__war AttributeError: 'TestObj' object has no attribute '__war' >>> t.__har Traceback (most recent call last): File "<input>", line 1, in <module> t.__har AttributeError: 'TestObj' object has no attribute '__har' >>> t.foo() Traceback (most recent call last): File "<input>", line 1, in <module> t.foo() AttributeError: 'TestObj' object has no attribute 'foo' >>> t._TestObj__war 'world' >>> t._TestObj__har 'hello' >>> t._TestObj__foo() helloworld
__slots__
类属性
正常状况下,当咱们定义了一个 class,建立了一个 class 的实例后,咱们能够给该实例绑定任何属性和方法,这就是动态语言的灵活性。在 Python 中默认用字典来存储实例的属性。示例:
#Python学习交流群:778463939 >>> class A(): ... pass ... >>> a = A() >>> a.name = "huoty" >>> a.age = 25 >>> print a.name huoty >>> print a.age 25 >>> a.__dict__ {'age': 25, 'name': 'huoty'}
字典位于实例的“心脏” 。__dict__
属性跟踪全部实例属性。举例来讲,你有一个实例 inst,它有一个属性 foo,那使用 inst.foo 来访问它与使用inst.__dict__['foo']
来访问是一致的。
字典会占据大量内存,若是你有一个属性数量不多的类,但有不少实例,那么正好是这种状况。为内存上的考虑,可使用 __slots__
属性来替代 __dict__
。
,__slots__
是新式类的特性。基本上,__slots__
是一个类变量,由一序列对象组成,由全部合法标识构成的实例属性的集合来表示。它能够是一个列表,元组或可迭代对象。也能够是标识实例能拥有的惟一的属性的简单字符串。任何试图建立一个其名不在__slots__
中的名字的实例属性都将致使 AttributeError 异常:
>>> class SlotedClass(object): ... __slots__ = ("foo", "bar") ... ... >>> c = SlotedClass() >>> c.foo = 42 >>> c.bar = "hello" >>> c.goo = "don't think so" Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'SlotedClass' object has no attribute 'goo'
这种特性的主要目的是节约内存。其反作用是某种类型的"安全",它能防止用户为所欲为的动态增长实例属性。带 __slots__
属性的类定义不会存在__dict__
了(除非你在 __slots__
中增长__dict__
元素)。