分类: Python技术

Python技术

让python类直接被调用

让python类直接被调用

之前在pytorch和keras中经常发现一个类model被直接调用,发现很有意思。于是就去看了看pytorch中nn.Module的源码,发现是定义了__call__(self)函数再去调用forward()函数。举个例子如下:

import math
class Pow(object):
def __init__(self,n=2):
self.n=n
super(Pow,self).__init__()
def forward(self,x):
return math.pow(x,self.n)
def __call__(self,x):
return self.forward(x)
l=Pow(2)
y=l(10)
print(y) #输出结果是100
l=Pow(3)
y=l(10)
print(y) #输出结果是1000

python 类的子类

python 类的子类

看下面的代码,请仔细阅读,并看看是否能够发现点什么问题呢?

#!/usr/bin/env python
#coding:utf-8

class Person:
def __init__(self, name, lang, email):
self.name = name
self.lang = lang
self.email = email

def author(self):
return self.name

class Programmer:
def __init__(self, name, lang, email, system, website):
self.name = name
self.lang = lang
self.email = email
self.system = system
self.website = website

def pythoner(self):
pythoner_list = [ self.name, self.lang, self.email, self.system, self.website ]
return pythoner_list

if __name__==”__main__”:
writer = Person(“hiekay”,”Chinese”,”hiekay@gmail.com”)
python = Programmer(“hiekay”,”Python”,”hiekay@gmail.com”,”Ubutun”,”hiekay.github.io”)
print “My name is:%s”%writer.author()
print “I write program by:%s”%python.pythoner()[1]

上面这段代码,运行起来没有什么问题,但是,仔细看,发现有两个类,一个名字叫做Person,另外一个叫做Programmer,这还不是问题所在,问题所在是这两个类的构造函数中,存在这相同的地方:self.name=name,self.lang=lang,self.email=email,这对于追求代码质量的程序员,一般是不允许的。*好不要有重复代码或者冗余代码。可是,在两个类中都要有这些参数,应该怎么办呢?

子类、父类和继承
看下面的代码,里面有两个类A,B。这段程序能够正确运行,每个类的功能是仅仅打印指定的内容。

#!/usr/bin/env python
#coding:utf-8

class A:
def __init__(self):
print “aaa”

class B:
def __init__(self):
print “bbb”

if __name__==”__main__”:
a = A()
b = B()

#运行结果
aaa
上面的两个类彼此之间没有所谓的父子关系。现在稍加改变,将类B改写,注意观察与上面的差异。

#!/usr/bin/env python
#coding:utf-8

class A:
def __init__(self):
print “aaa”

class B(A): #这里和上面程序不同。B继承了A
def __init__(self):
print “bbb”

if __name__==”__main__”:
a = A()
b = B()

#运行结果
这段程序中,类B跟前面的那段有一点不同,class B(A):,这样写就表明了B相对A的关系:B是A的子类,B从A继承A的所有东西(子承父业)。

但是,运行结果一样。是的,那是以为在B中尽管继承了A,但是没有调用任何A的东西,就好比儿子从老爸那里继承了财富,但是儿子一个子也没动,外界看到的和没有继承一样。

#!/usr/bin/env python
#coding:utf-8

class A:
def __init__(self):
print “aaa”

class B(A):
def __init__(self):
#print “bbb”
A.__init__(self) #运行继承的父类

if __name__==”__main__”:
a = A()
b = B()

#运行结果

这回运行结果有了变化,本来b=B()是运行类B,但是B继承了A,并且在初始化的构造函数中,引入A的构造函数,所以,就运行A的结果相应结果了。

下面把*开头的那端程序用子类继承的方式重写,可以是这样的:

#!/usr/bin/env python
#coding:utf-8

class Person:
def __init__(self, name, lang, email):
self.name = name
self.lang = lang
self.email = email

def author(self):
return self.name
“””
class Programmer:
def __init__(self, name, lang, email, system, website):
self.name = name
self.lang = lang
self.email = email
self.system = system
self.website = website

def pythoner(self):
pythoner_list = [ self.name, self.lang, self.email, self.system, self.website ]
return pythoner_list
“””

class Programmer(Person): #继承父类Person
def __init__(self, name, lang, email, system, website):
Person.__init__(self,name,lang,email) #将Person.__init__()的功能继承到这里
#self.name = name #这三句是Person中已经搞定的,就不用重复
#self.lang = lang #通过继承已经实现了这三句的功能
#self.email = email
self.system = system #子类中不同于Person父类部分
self.website = website

def pythoner(self):
pythoner_list = [ self.name, self.lang, self.email, self.system, self.website ]
return pythoner_list

if __name__==”__main__”:
writer = Person(“hiekay”,”Chinese”,”hiekay@gmail.com”)
python = Programmer(“hiekay”,”Python”,”hiekay@gmail.com”,”Ubutun”,”hiekay.github.io”)
print “My name is:%s”%writer.author()
print “I write program by:%s”%python.pythoner()[1]
1
代码运行结果与前面一样。

需要提供注意的是,在子类中,如果要继承父类,必须用显明的方式将所继承的父类方法写出来,例如上面的Person.init(self,name,lang,email),必须这样写,才能算是在子类中进行了继承。如果不写上,是没有继承的。用编程江湖的黑话(比较文雅地称为“行话”)说就是“显式调用父类方法”。

对于为什么要用继承:

从技术上说,OOP里,继承*主要的用途是实现多态。对于多态而言,重要的是接口继承性,属性和行为是否存在继承性,这是不一定的。事实上,大量工程实践表明,重度的行为继承会导致系统过度复杂和臃肿, 反而会降低灵活性。因此现在比较提倡的是基于接口的轻度继承理念。这种模型里因为父类(接口类)完全没有代码,因此根本谈不上什么代码复用了。

在Python里,因为存在Duck Type,接口定义的重要性大大的降低,继承的作用也进一步的被削弱了。

另外,从逻辑上说,继承的目的也不是为了复用代码,而是为了理顺关系。

python类方法的使用

python类方法的使用

分类专栏: python编程 文章标签: python类方法的使用 python中@classmethod使用 @classmethod使用 isinstance()函数判断对象类型 python判断对象类型
版权
python类方法的使用
一、python类方法的特性
二、测试示例
三、使用isinstance()函数判断对象类型
一、python类方法的特性
1、与静态方法一样,类方法可以通过类名调用类方法。
2、与静态方法一样,类成员方法无法访问对象实体变量,可以访问类的静态变量。
3、类方法需要传入代表本类的cls参数。
4、使用@classmethod定义类方法。

二、测试示例
class ClassFunc:
var1 = “string1” #类的静态变量

def __init__(self):
self.var2 = ‘string2’ # 实例变量,在类方法中无法访问

@classmethod
def class_func(cls):
print(str(cls)+” can visit var1:”+cls.var1)
print(str(cls)+” can’t visit var2″)
1
2
3
4
5
6
7
ClassFunc.class_func()

cFunc = ClassFunc() cFunc.class_func()

运行结果如下:%title插图%num

三、使用isinstance()函数判断对象类型
1、使用isinstance()函数可以检测给定的对象是否属于或者继承于某个类或者类型,如果是返回True,否则返回False。

2、测试示例:

class MyIsInstance:
def init(self):
pass

myInstance = MyIsInstance() print(isinstance(myInstance,MyIsInstance))

运行结果:%title插图%num

说明:如有错误,欢迎指正。。。

C调用python类的正确方法

C或C++调用python一般都可以使用python自带的库完成,首先添加python.h的头文件,链接时加上对应的库即可。

但是在C/C++程序中使用到python的类时会遇到很多坑,网上搜会得到很多相似的方法如下所示

首先声明,以下的方法是有问题的,有问题的地方我会使用红字标出

注: 下述所有导入方法在导入失败时不会报错, 只会返回空指针.

*步是导入.py文件:

使用PyObject* pModule来存储导入的.py文件模块, 调用的方法是PyImport_ImportModule(path):  PyObject* pModule = PyImport_ImportModule(“testpy”); 
使用PyObject* pDict来存储导入模块中的方法字典, 调用的方法是PyModule_GetDict(module):  PyObject* pDict = PyModule_GetDict(pModule); 
这样就完成了.py文件的导入.

第二步是导入已导入模块中的方法或类:

获取方法, 调用的方法是PyDict_GetItemString(dict, methodName): PyObject* pFunHi = PyDict_GetItemString(pDict, “sayhi”); 
获取类, 调用的方法同上, 注意红体部分的字符串对应于.py文件中的类/方法名:  PyObject* pClassSecond = PyDict_GetItemString(pDict,”Second”); 
第三步是使用导入的方法或类:

使用方法, 调用PyObject_CallFunction(pFunc, “s”, args)即可:  PyObject_CallFunction(pFunHi, “s”, “lhb”); 
使用类构造对象, 调用PyInstance_New(pClass, NULL, NULL)即可:  PyObject* pInstanceSecond = PyInstance_New(pClassSecond, NULL, NULL); , 注意其中的pClassSecond为第二步.2中获取的类指针
使用类对象的方法, 调用PyObject_CallMethod(pInstance, methodname, “O”, args)即可:  PyObject_CallMethod(pInstanceSecond,”invoke”, “O”, pInstancePerson); 
上述调用中的”s”和”O”代表的是参数列表的类型, 我们可以在 Py_BuildValue 找到所有的类型, 本文*后也附了此表.
PyInstance_New是python2使用的函数,python3则使用新的函数PyInstanceMethod_New,国内很多文章都认为这两个函数返回的是类的实例对象,其实不然,它们返回的是该类的构造函数对象。

按照上面文章的步骤做在不涉及修改类的成员变量时是没有问题的,如果有python类

class Test:
def __init__(self):
self.i = 1
print(“init!”)

def modify(self):
self.i+=1

def do(self):
print(self.i)
如果使用上面的方法使用这个类,调用do方法是不会有问题的,可以成功打印,但是如果调用modify则会报错,PyErr_Print打印错误信息则会提示i不存在。

并且在PyInstance_New或PyInstanceMethod_New时并不会打印init!,说明构造函数根本没有被调用。

正确的调用方式则应该是

PyObject* pConstruct = PyInstanceMethod_New(pClass);
PyObject* pIns = PyObject_CallObject(pConstruct,nullptr);
PyObject_CallMethod(pIns,”modify”, nullptr); 
PyObject_CallMethod(pIns,”do”, nullptr); 
使用PyInstanceMethod_New获得构造函数后才能构造对象,并且调用时不需要传递自身。

Python分类求和方法

Python分类求和方法

Python分类求和方法,Excel表格数据为例。
在Excel中经常会有根据列分类求和的需求,如果数据较少,可以在Excel中通过手动筛选的方法,但是数据较多那就比较麻烦啦。
这里需要用到groupby函数,pandas提供了一个灵活高效的groupby功能,它使你能以一种自然的方式对数据集进行切片、切块、摘要等操作。根据一个或多个键(可以是函数、数组或DataFrame列名等)拆分pandas对象。计算分组摘要统计,如计数、平均值、标准差,或用户自定义函数。对DataFrame的列应用各种各样的函数。应用组内转换或其他运算,如规格化、线性回归、排名或选取子集等。计算透视表或交叉表。执行分位数分析以及其他分组分析。
这里只简单举个例子,利用groupby函数在Excel表格中分类求和的简单实现。
需求分析,现有如下表格
%title插图%num

需要按照不同月份汇总value值,这里可以用groupby函数简单实现。
%title插图%num
import pandas as pd
df=pd.read_excel(‘F:\邮件张\wan.xlsx’)
df_sum = df.groupby(‘month’)[‘value’].sum()
df_sum.to_excel(‘F:\邮件张\汇总.xlsx’)
1
2
3
4
*终得到新建汇总表格如下%title插图%num

可以利用Python得到按照列分类的汇总。

Python风格的对象

符合Python风格的对象

Python的私有属性和受保护的属性:

如果有人编写了Dog类,这个类内部用到了mood实例属性,但是没有将其开放。

现在,你创建了Dog类的子类:Beagle。如果你在毫不知情的情况下又创建了名为mood的实例属性,那么在继承的方法中就会把Dog类的mood属性覆盖掉。

名称改写:

为了避免这个情况,如果以__mood的形式命名实例属性,Python会把属性存入实例的__dict__属性中,而且会在前面加上一个下划线和类名。

因此,对Dog类来说,__mood会变成_Dog__mood;对Beagle来说,会变成_Beagle__mood。这个特性就是名称改写。

约定俗成:

对于不喜欢使用名称改写的人,他们约定使用一个下划线前缀编写的“受保护”的属性。(如:_MyThing_blahblah)

类似于使用全大写字母表示一个常量。

__slots__类属性节省空间:

默认情况下,Python在各个实例中名为__dict__的字典里存储实例属性,字典会消耗大量内存。

继承自父类的__slots__属性没有效果。Python只会使用各个类当前类中定义的__slots__属性。

创建一个类属性__slots__,把它的值设为一个字符串构成的可迭代对象,其中各个元素表示各个实例属性。

class Vector:

__slots__ = (‘__x’,’__y’)
在类中定义了__slots__属性之后,实例不能再有__slots__中所列名称之外的其他属性。

如果类中定义了__slots__属性,而且想把实例作为弱引用的目标,要把’__weakref__’添加到__slots__中。

实例只能拥有__slots__属性,除非把”__dict__”加入到__slots__中后,会支持动态创建属性。

覆盖类属性:

类属性可用于为实例属性提供默认值。

如果为不存在的实例属性赋值,会新建实例属性。

如果想修改类属性的值,必须直接在类上修改,不能通过实例修改。

如果想修改所有实例的XX属性的默认值,可以通过 类.XX 修改

定义类(class)的语法

python定义类(class)的语法,

定义类(class)的语法

class Iplaypython:               #类的名字,首字母,有一个不可文的规定,*好是大写,这样需要在代码中识别区分每个类。
>>>     def fname(self, name):   #第二行开始是类的方法,大家看到了,和函数非常相似,但是与普通函数不同的是,它的内部有一个“self”,参数,它的作用是对于对象自身的引用。
>>>           self.name = name

玩蛇网是一个学习python比较好的网站

http://www.iplaypy.com/jinjie/

2)_init_函数(方法)

首先说一下,带有两个下划线开头的函数是声明该属性为私有,不能在类地外部被使用或直接访问。

类的实例(类的调用)、类的方法、构造函数、类的命名空间和作用域以及类的继承概念

Python类的定义

Python类的定义

必须知道的概念
类 Class: 用来描述具体相同的属性和方法的对象的集合。定义了该集合中每个对象所共有的属性和方法。对象是类的示例。

类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。

实例变量:定义在方法中的变量,只作用于当前实例的类。

数据成员:类变量或者实例变量用于处理类及其实例对象的相关数据。

方法:类中定义的函数。在类内部,使用 def 关键字来定义一个方法,与一般函数定义不同,类方法必须包含参数 self, 且为*个参数,self 代表的是类的实例。

构造函数:即__init()__,特殊的方法,在对象创建的时候被自动调用。

析构函数:即__del()__,特殊的方法,在对象被销毁时被自动调用。

实例化:创建一个类的实例,类的具体对象。就是将创建的类赋值给另一个变量。理解为赋值即可,a = class(),这个过程,就叫做实例化

对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,这是模拟”是一个(is-a)”关系(例图,Dog是一个Animal)。

方法重写:如果从父类继承的方法不能满足子类的需求,可以对其 进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。

构造函数—— “ __init__()”
当类被实例化时自动执行的函数 __init__(),如果没有写自定义的构造函数,则会执行默认构造函数,该默认构造函数”什么也不干”。

 

析构函数——“__del__”
__del__()也是可选的,如果不提供,则Python 会在后台提供默认析构函数。当使用del 删除对象时,会调用他本身的析构函数,另外当对象在某个作用域中调用完毕,在跳出其作用域的同时析构函数也会被调用一次,这样可以用来释放内存空间。

可显示调用析构函数,使用del语句——“del  + 对象名”

 

属于类级别的变量,在使用它的时候一定要带上类型名字 比如 MyClass.count

属于每个对象级别的变量,在调用的时候一定要带上self表明属于当前对象。self.name

 

类中的self到底是干啥的
首先需要知道的是self只有在类的方法中才会有,且self在定义类的方法时是必须有的,但是在调用时不必传入相应的参数。

另外,self名称不是必须的,在python中self不是关键词,你可以定义成a或b或其它名字都可以。%title插图%num

class Person:
def _init_(myname,name):
myname.name=name
def sayhello(myname):
print(‘My name is:’,myname.name)
p=Person(‘Bill’)
print(p)
*后,self指的是类实例对象本身(注意:不是类本身)。%title插图%num%title插图%num

class Test:
def ppr(self):
print(self)
print(self.__class__)

t = Test()
t.ppr()
执行结果:
<__main__.Test object at 0x000000000284E080>
<class ‘__main__.Test’>
在上述例子中,self指向的是t这个对象,而不是类本身。在Python解释器的内部,当我们调用t.ppr()时,实际上Python解释成Test.ppr(t),也就是把self替换成了类的实例。

class Test:
def ppr():
print(self)

t = Test()
t.ppr()

运行结果:
Traceback (most recent call last):
File “cl.py”, line 6, in <module>
t.ppr()
TypeError: ppr() takes 0 positional arguments but 1 was given

class Test:
def ppr():
print(__class__)

Test.ppr()

运行结果:
<class ‘__main__.Test’>
类的私有变量、保护变量
私有变量:在类里面,在一个成员变量前加上“__”表示该变量是该类私有的,不能在外部通过类对象访问,只能在类的内部被使用。

保护变量:在类里面,在一个成员变量前加上“_”表示该变量是该类被保护的,这样的变量是可以在外部通过类的对象来访问的,但它的意思是“虽然我可以被访问,但是,请把我视为私有变量,不要随意访问”

注意:在Python中,变量名类似__xxx__的,也就是以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,不是私有变量。

继承
继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”,继承的过程,就是从一般到特殊的过程。在某些 OOP 语言中,一个子类可以继承多个基类。但是一般情况下,一个子类只能有一个基类,要实现多重继承,可以通过多级继承来实现。

单继承
什么是单继承:一个子类只从一个父类派生。

构造函数书写问题:

1.python中如果子类有自己的构造函数,不会自动调用父类的构造函数,如果需要用到父类的构造函数,则需要在子类的构造函数中显式的调用。

2.如果子类没有自己的构造函数,则会直接从父类继承构造函数,这在单继承(一个子类只从一个父类派生)中没有任何理解上的问题。

3.如何调用父类的构造函数

a.经典类的写法: 父类名称.__init__(self,参数1,参数2,…)

b. 新式类的写法:super(子类,self).__init__(参数1,参数2,….)

 

Python类属性和方法的调用

Python从设计之初就已经是一门面向对象的语言,正因为如此,在Python中创建一个类和对象是很容易的。

一、类、对象概述
在面向对象程序设计中,把数据以及对数据的操作封装在一起,组成一个整体(对象),不同对象之间通过消息机制来通信或者同步。对于相同类型的对象进行分类、抽象后,得出共同的特征而形成了类。
类的抽象具体包括两个方面:
1.数据抽象:描述某类对象共有的属性或状态。
2.过程抽象:描述某类对象共有的行为或功能操作。
在python中,使用类来定义同一种类型的对象。类是广义的数据类型,能够定义复杂数据的特性,包括:
1.静态特性(即数据抽象):创建类时用变量形式表示对象特征的成员称为属性(数据成员)。
2.动态特性(即行为抽象,也就是对数据的操作方法):用函数形式表示对象行为的成员称为成员方法,数据成员和成员方法统称为类的成员。
类是实现代码复用和设计复用的一个重要方法,封装、继承、多态是面向对象程序设计的三个要素。
类是生成对象的抽象模板,对象是根据类创建出来的一个个具体的实例。
二、类的定义与使用
Python使用class关键字来定义类,class关键字之后是一个空格,接下来是类的名字,如果派生自其它基类的话则需要把所有父类放到一对圆括号中并使用逗号分隔,然后是一个冒号,*后换行并定义类的内部实现。
类名的首字母一般要大写。
class Car(object): #定义一个类,派生自object类(所有类的祖先,定义类时不存在其他父类就写object)
can_move=True #定义类属性
def infor(self): #定义成员方法
print(“This is a car”)
1
2
3
4
类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的*个参数名称, 按照惯例它的名称是 self(self代表类的实例,而非类;self 不是 python 关键字,我们把他换成其他也是可以正常执行的)。
三、类属性和类方法的调用
定义了类之后,就可以用来实例化对象,并通过“对象名.成员”的方式来访问其中的数据成员或成员方法。

>>>spring=Bird() #实例化对象
>>>print(Bird.have_feather) #通过类名调用属性
>>>print(Bird.have_head) #通过对象名调用属性
>>>spring.move() #通过对象名调用方法
>
1
2
3
4
5

类方法大体分为 3 类,分别是类方法、实例方法和静态方法,其中实例方法用的是*多的。我们知道,实例方法的调用方式其实有 2种,既可以采用类对象调用,也可以直接通过类名调用。
通常情况下,我们习惯使用类对象调用类中的实例方法。但如果想用类调用实例方法,不能像如下这样:

class Study:
def info(self):
print(“学 Python”)
#通过类名直接调用实例方法
Study.info()
1
2
3
4
5
运行上面代码,程序会报出如下错误:

Traceback (most recent call last):
File “D:\python3.6\demo.py”, line 5, in <module>
Study.info()
TypeError: info() missing 1 required positional argument: ‘self’
1
2
3
4
其中,*后一行报错信息提示我们,调用 info() 类方式时缺少给 self 参数传参。这意味着,和使用类对象调用实例方法不同,通过类名直接调用实例方法时,Python 并不会自动给 self 参数传值。
读者想想也应该明白,self 参数需要的是方法的实际调用者(是类对象),而这里只提供了类名,当然无法自动传值。

因此,如果想通过类名直接调用实例方法,就必须手动为 self 参数传值。例如修改上面的代码为:

class Study:
def info(self):
print(“学 Python”)
clang = Study()
#通过类名直接调用实例方法
Study.info(clang)
1
2
3
4
5
6
再次运行程序,结果为:

学 Python
1
可以看到,通过手动将 clang 这个类对象传给了 self 参数,使得程序得以正确执行。实际上,这里调用实例方法的形式完全是等价于 clang.info()。

值得一提的是,上面的报错信息只是让我们手动为 self 参数传值,但并没有规定必须传一个该类的对象,其实完全可以任意传入一个参数,例如:

class Study:
def info(self):
print(self,”学 Python”)
#通过类名直接调用实例方法
Study.info(“zhangsan”)
1
2
3
4
5
运行结果为:

zhangsan 学 Python
1
可以看到,“zhangsan” 这个字符串传给了 info() 方法的 self 参数。显然,无论是 info() 方法中使用 self 参数调用其它类方法,还是使用 self 参数定义新的实例变量,胡乱的给 self 参数传参都将会导致程序运行崩溃。

总的来说,Python 中允许使用类名直接调用实例方法,但必须手动为该方法的*个 self 参数传递参数,这种调用方法的方式被称为“非绑定方法”。
用类的实例对象访问类成员的方式称为绑定方法,而用类名调用类成员的方式称为非绑定方法。
(此处参考)

四、私有成员与公有成员
私有成员在类的外部不能直接访问,一般是在类的内部进行访问和操作,或者在类的外部通过调用对象的公有成员方法来访问,而公有成员是可以公开使用的,既可以在类的内部进行访问,也可以在外部程序中使用。
从形式上看,在定义类的成员时,如果成员名以两个下划线开头但是不以两个下划线结束则表示是私有成员,否则就不是私有成员。
Python并没有对私有成员提供严格的访问保护机制,通过一种特殊方式“对象名._类名__xxx”也可以在外部程序中访问私有成员,但这会破坏类的封装性,不建议这样做。

在Python中,以下划线开头的变量名和方法名有特殊的含义,尤其是在类的定义中。
_xxx:受保护成员;
__xxx__:系统定义的特殊成员;
__xxx:私有成员,只有类对象自己能访问,子类对象不能直接访问到这个成员,但在对象外部可以通过“对象名._类名__xxx”这样的特殊方式来访问。
1
2
3
注意:Python中不存在严格意义上的私有成员。
————————————————

Python类的定义与使用

Python类的定义与使用

 

目标:

1.类的定义

2.父类,子类定义,以及子类调用父类

3.类的组合使用

4.内置功能

 

1.类的定义

代码如下:

 

  1. #!/usr/bin/env python
  2. #coding:utf8
  3. class Hotel(object):
  4. “””docstring for Hotel”””
  5. def __init__(self, room, cf=1.0, br=15):
  6. self.room = room
  7. self.cf = cf
  8. self.br = br
  9. def cacl_all(self, days=1):
  10. return (self.room * self.cf + self.br) * days
  11. if __name__ == ‘__main__’:
  12. stdroom = Hotel(200)
  13. big_room = Hotel(230, 0.9)
  14. print stdroom.cacl_all()
  15. print stdroom.cacl_all(2)
  16. print big_room.cacl_all()
  17. print big_room.cacl_all(3)

 

2.父类、子类以及调用父类

代码如下:

 

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # 父类
  4. class AddBook(object):
  5. def __init__(self, name, phone):
  6. self.name = name
  7. self.phone = phone
  8. def get_phone(self):
  9. return self.phone
  10. # 子类,继承
  11. class EmplEmail(AddBook):
  12. def __init__(self, nm, ph, email):
  13. # AddBook.__init__(self, nm, ph) # 调用父类方法一
  14. super(EmplEmail, self).__init__(nm, ph) # 调用父类方法二
  15. self.email = email
  16. def get_email(self):
  17. return self.email
  18. # 调用
  19. if __name__ == “__main__”:
  20. Detian = AddBook(‘handetian’, ‘18210413001’)
  21. Meng = AddBook(‘shaomeng’, ‘18210413002’)
  22. print Detian.get_phone()
  23. print AddBook.get_phone(Meng)
  24. alice = EmplEmail(‘alice’, ‘18210418888’, ‘alice@xkops.com’)
  25. print alice.get_email(), alice.get_phone()

 

3.类的组合使用

代码如下:

 

 

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. ”’
  4. 1.class类的组合使用
  5. 2.手机、邮箱、QQ等是可以变化的(定义在一起),姓名不可变(单独定义)。
  6. 3.在另一个类中引用
  7. ”’
  8. class Info(object):
  9. def __init__(self, phone, email, qq):
  10. self.phone = phone
  11. self.email = email
  12. self.qq = qq
  13. def get_phone(self):
  14. return self.phone
  15. def update_phone(self, newphone):
  16. self.phone = newphone
  17. print “手机号更改已更改”
  18. def get_email(self):
  19. return self.email
  20. class AddrBook(object):
  21. ”’docstring for AddBook”’
  22. def __init__(self, name, phone, email, qq):
  23. self.name = name
  24. self.info = Info(phone, email, qq)
  25. if __name__ == “__main__”:
  26. Detian = AddrBook(‘handetian’, ‘18210413001’, ‘detian@xkops.com’, ‘123456’)
  27. print Detian.info.get_phone()
  28. Detian.info.update_phone(18210413002)
  29. print Detian.info.get_phone()
  30. print Detian.info.get_email()

 

 

 

4.内置功能(函数()加与不加的区别)

代码如下:

 

 

  1. #!/usr/bin/env python
  2. #coding:utf8
  3. class Books(object):
  4. def __init__(self, title, author):
  5. self.title = title
  6. self.author = author
  7. def __str__(self):
  8. return self.title
  9. def __repr__(self):
  10. return self.title
  11. def __call__(self):
  12. print “%s is written by %s” %(self.title, self.author)
  13. if __name__ == ‘__main__’:
  14. pybook = Books(‘Core Python’, ‘Wesley’)
  15. print pybook
  16. pybook()

 

  1. #!/usr/bin/env python
  2. #coding:utf8
  3. class Number(object):
  4. “””Custum object
  5. add/radd -> +;
  6. sub/rsub -> -;
  7. mul/rmul -> *;
  8. div/rdiv -> /;
  9. “””
  10. def __init__(self, number):
  11. self.number = number
  12. def __add__(self, other):
  13. return self.number + other
  14. def __radd__(self, other):
  15. return self.number + other
  16. def __sub__(self, other):
  17. return self.number – other
  18. def __rsub__(self, other):
  19. return other – self.number
  20. def __gt__(self, other):
  21. if self.number > other:
  22. return True
  23. return False
  24. if __name__ == ‘__main__’:
  25. num = Number(10)
  26. print num + 20
  27. print 30 + num
  28. print num – 5
  29. print 11 – num
  30. print num > 20

 

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速