类和对象
如需创建类,使用class
关键字。
对象 = 属性+方法
class Turtle: #Python中的类名以大写开头
#属性
color='green'
weight=10
legs=4
shell=True
mouth='大嘴'
#方法
def climb(self):
print('努力向前爬')
def run(self) :
print('您见过飞驰的乌龟吗?')
def eat(self) :
print('吃嘛嘛香!')
>>> tt=Turtle()
>>> tt.run()
您见过飞驰的乌龟吗?
>>>
方法里的self是必须加的!!!,不加会报错,self就是用于代表初始化的到的实例。 本来可以设置为不加self,但这样就得有个关键字指代实例,例如java和js中用this来指代。然而python的设计哲学就是"Explicit is better than implicit."显示总比隐示好,所以就加了个self。
面向对象的特征:
封装、继承、多态
python的继承是这么来的:
class MyList(list):
pass
list2 = MyList()
list2.append(),....这里就可以使用list里的方法了。
也就是:
class sonClassName(parentClassName):
#逻辑处理
Tips:关于方法体里的self:
self只有在类的方法中才会有,独立的函数或方法是不必带有self的。self在定义类的方法时是必须有的,必须是类中方法的首个参数!,虽然在调用时不必传入相应的参数。self名称不是必须的,在python中self不是关键词,你可以定义成a或b或其它名字都可以,但是约定成俗(为了和其他编程语言统一,减少理解难度)。
class Ball:
def setName(self,name):
self.name=name
def kick(self):
print('我叫%s,你特么别踢我!'%self.name)
>>> a=Ball()
>>> a.setName('Jack')
>>> b=Ball()
>>> b.setName('Bob')
>>> a.kick()
我叫Jack,你特么别踢我!
>>> b.kick()
我叫Bob,你特么别踢我!
>>>
__init__()
函数
所有类都一个名为__init__()
函数,它始终在启动类时执行。
故当我们需要在构造的时候进行某些操作,就可以重写此函数,来添加我们的逻辑。
在子类不重写__init__
方法时,子类会默认调用父类中的__init__
方法
子类也可以重写__init__
方法,来给子类定义专属属性
每次使用类创建新对象时,都会自动调动__init__()
函数。
修改对象属性
p1.age = 40
删除对象属性
del p1.age
删除对象
del p1
私有变量、公有变量
>>> class Bd:
name='Sword'
>>> c=Bd()
>>> c.name
'Sword'
>>>
像这种,实例可以直接访问到的就是公有变量,而如果想讲变量变成私有,只需要在变量前加上__
(双下划线)。
ex:
>>> class Bd:
__name='Sword'
>>> c=Bd()
>>> c.__name
Traceback (most recent call last):
File "<pyshell#43>", line 1, in <module>
c.__name
AttributeError: 'Bd' object has no attribute '__name'
>>>
这样就不可以访问到了,如果想访问私有变量,有两种方法:
1.get方法:
>>> class Bd:
__name='Sword'
def getName(self):
return self.__name
>>> c=Bd()
>>> c.getName()
'Sword'
>>>
2.实例名._类名__变量名,ex:
>>> c._Bd__name
'Sword'
继承
要创建从其他类继承功能的类,需要在创建子类是将父类作为参数发送。
class 子类(父类):...
ex:
class Person:
x = 0
y = ""
def __init__(self):
self.x = 86
self.y = "HaSaKei!"
def print_person(self):
print("x: {}".format(self.x))
# person = Person()
# person.print_person()
# 继承
class Student(Person):
def __init__(self):
super().__init__()
self.x = 22
def print_x(self):
print(self.x)
student = Student()
student.print_x()
如果调用父类的属性,就跟上面说的是一样的。
如上所示,可以通过super()
函数,使子类从其父类继承所有方法和属性。
import random as r
class Fish:
def __init__(self):
self.x=r.randint(0,10)
self.y=r.randint(0,10)
def move(self):
self.x-=1
print('My Pos Is:',self.x,self.y)
class Goldfish(Fish):
pass
class Carp(Fish):
pass
class Shark(Fish):
def __init__(self):
self.hungry=True
def eat(self):
if self.hungry:
print('Fighting!!Eat!')
self.hungry=False
else :
print('太撑了,吃不下了!')
这时候如果实例化Shark(),调用父类的move方法,就会报错的:
>>> shark=Shark()
>>> shark.move()
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
shark.move()
File "C:\Users\18041\Desktop\classParent.py", line 7, in move
self.x-=1
AttributeError: 'Shark' object has no attribute 'x'
因为重写了init方法,子类重写了父类的方法,就给覆盖掉了。如果想保留父类的方法,有两个途径:
1.调用为绑定的父类方法
2.调用super方法
第一种:
class Shark(Fish):
def __init__(self):
Fish.__init__(self)
self.hungry=True
def eat(self):
if self.hungry:
print('Fighting!!Eat!')
self.hungry=False
else :
print('太撑了,吃不下了!')
对比之前的,多了个:Fish.__init__(self)
这样就可以了。
>>> shark=Shark()
>>> shark.move()
My Pos Is: 1 9
>>> shark.move()
My Pos Is: 0 9
>>> shark.eat()
Fighting!!Eat!
>>>
2.第二种方法调用super()函数,把Fish.__init__(self)
替换为super().__init__(self)
。即可
多重继承
class DerivedClassName(Base1,Base2…)
就是定义的时候传入多个父类,然后可以调用多个父类的属性和方法。但是这个很容易导致不知名的bug,这个往往很致命。不推荐使用。
组合
当类与类之间通过继承关系很难实现的时候,还有一种方式就是组合。实际上也是很常见的,总不可能两个稍微有点关系的类就得通过继承来表示关系吧,就像你跟别人谈个话,总不能当他爹或者认他当爹吧。ex:
class Turtle:
def __init__(self,x):
self.num=x
class Fish:
def __init__(self,x):
self.num=x
class Pool:
def __init__(self,x,y):
self.turtle=Turtle(x)
self.fish=Fish(y)
def print_num(self):
print('水池里总共有乌龟%d只,小鱼%d条'%(self.turtle.num,self.fish.num))
>>> pool=Pool(5,6)
>>> pool.print_num()
水池里总共有乌龟5只,小鱼6条
>>>
还有一些需要注意的地方,ex:
>>> class TestClass:
def x(self):
print('X-man!')
>>> c=TestClass()
>>> c.x=12
>>> c.x
12
>>> c.x()
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
c.x()
TypeError: 'int' object is not callable
>>>
变量名不要和方法名一样!
什么是绑定?
Python严格要求方法需要有实例才能被调用,这种限制其实就是Python所谓的绑定概念
此外,在介绍一个方法:
类名/实例名.__dict__
查看类属性
类和对象一些相关的BIF
1.issubclass(class,classinfo)
如果第一个类是第二个类的子类,就返回True;
(
1>一个类被认为是自身的子类
2>classinfo可以是类对象组成的元组,只要class与其中任何一个候选类的子类,则返回True
)ex:
>>> class A:
pass
>>> class B(A):
pass
>>> class C:
pass
>>> issubclass(A,B)
False
>>> issubclass(B,A)
True
>>> issubclass(B,(A,C))
True
>>> issubclass(B,object)
True
2.isinstance(object,classinfo)
检查一个对象是否是一个类的实例对象
(
1>如果第一个参数不是对象,则永远返回False
2>如果第二个参数不是类或者由类对象组成的元组,会抛出一个TypeError
)
3.hasattr(object,name)
检查对象是否有特定属性
>>> hasattr(C,'height')
False
>>>
4.getattr(object,name[,default])
获取对象的属性,如果没有属性,会抛出异常的
>>> getattr(C,'weight')
Traceback (most recent call last):
File "<pyshell#34>", line 1, in <module>
getattr(C,'weight')
AttributeError: type object 'C' has no attribute 'weight'
>>> getattr(C,'weight','您访问的属性根本特么就没有!!!!!!!!!')
'您访问的属性根本特么就没有!!!!!!!!!'
>>>
5.setattr(object,name,value)
给对象设置属性
6.delattr(object,name)
删除属性
7.property(fget=None,fset=None,fdel=None,
doc=None)
property()函数中的三个函数分别对应的是获取属性的方法、设置属性的方法以及删除属性的方法,这样一来,外部的对象就可以通过访问x的方式,来达到获取、设置或删除属性的目的。
当需要更改上例中的getSize、setSize或delSize函数的名称时,如果这些方法是作为接口让用户调用的,那么对用户而言就要修改自己调用的方法名,很麻烦,使用了proprty()后,用户就不需担心这种问题了。[自己本地改了方法名后只需要改一下对应property里的方法名即可,用户不需要动]
>>> class C:
def __init__(self,size=10):
self.size=size
def getSize(self):
return self.size
def setSize(self,value):
self.size=value
def delSize(self):
del self.size
x = property(getSize,setSize,delSize)
>>> c1=C()
>>> c1.getSize()
10
>>> c1.x
10
>>> c1.size
10
>>> c1.x=19
>>> c1.size
19
>>>
作用域
局部作用域
在函数内部创建的变量属于该函数的局部作用域,并且只能从该函数内部使用。
全局作用域
在python主体中创建的变量是全局变量,属于全局作用域。
全局变量在任何范围中可用。(全局和局部)
命名变量
如果在函数内部和外部操作同名变量,python会将它们视为两个单独的变量,一个在全局范围内可用,而另一个在局部范围内可用。
Global关键字
如果需要创建一个全局变量,在被卡在本地作用域内,则可以使用global关键字。
global关键字使变量成为全局变量。
模块
模块是包含一组函数的文件,可以在应用程序中引用。(就跟kt一样的文件,类不类的,都没什么的)
创建模块
如需创建模块,只需要将代码保存在文件扩展名为.py的文件中。(就是创建一个py文件)
使用模块
可以使用import
语句来导入我们创建的模块。
Ex:
可以看出引入模块后调用函数,正确输出。
as
关键字用于起别名。
内建模块
python中有几个内建模块,可以随时导入。
例如 import platform
使用dir()函数
dir()函数可以列出模块中的所有函数名!dir() 函数可用于所有模块,也可用于您自己创建的模块。
从模块导入
有时候我们可能不需要导入整个模块,可能只需要某个变量或者某个函数,这时候就可以用
from
关键字选择从模块中仅导入某个部件
日期
python中的日期不是其自身的数据类型(没有Date哦),但可以导入内置的datatime
模块,把日期视作日期对象来进行处理.(确定这一句不是废话么?)
创建日期对象
如果需要创建日期,可以使用datetime模块的datetime()类,此类需要三个参数:年、月、日。
strftime()方法
datetime
对象拥有把日期对象格式化为可读字符串的方法:
该方法名为strftime(),并使用一个format
参数来指定返回字符串的格式:
所有格式代码: