【3.1.1】认识python的类
断断续续的写过几个类之后,对类有了一些基本的认知。突然认识到去年年初的时候,小龚看了我的代码,来了一句,我靠,你的class里面怎么都是staticmethod呀?
一、类的属性
要知道一个类有哪些属性,有两种方法。最简单的是使用 dir() 内建函数。另外是通过访问类的字典属性 dict。
>>> dir(MyClass)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__form
at__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__',
'__lt__', '__module__', '__ne__', '__new__', '__qualname__', '__reduce__', '__r
educe_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook
__', '__weakref__', 'myVersion', 'showMyVersion']
>>> MyClass.__dict__
mappingproxy({'__module__': '__main__', '__qualname__': 'MyClass', '__weakref__'
: <attribute '__weakref__' of 'MyClass' objects>, 'showMyVersion': , '__dict__': <attribute '__dict__' of 'MyClass ' objects>, 'myVersion': '1.1', '__doc__': 'MyClass class definition'})
dir() 返回的仅是对象的属性的一个名字类表,而 __dict__
返回的是一个字典,它的键(key)是属性名,键值(value)是相应的属性对象的数据值。
特殊的类属性
C.__name__ 类C的名字(字符串)
C.__doc__ 类C的文档字符串
C.__bases__ 类C的所有父类构成的元组
C.__dict__ 类C的属性
C.__module__ 类C定义所在的模块
C.__class__ 实例C对应的类
__name__ 是给定类的字符名字。它适用于那种只需要字符串(类对象的名字),而非对象本身的情况。
__doc__是类的文档字符串,与函数及模块的文档字符串相似,必须紧随头行后的字符串。文档字符串不
能被派生类继承,也就是说派生类必须含有他们自己的文档字符串。__bases__用来处理继承,它包含了一个由所有父类组成的元组。__dict__属性包含一个字典,由类的数据属性组成。
>>> MyClass.__name__
'MyClass'
>>> MyClass.__doc__
'MyClass class definition'
>>> MyClass.__bases__
(<class 'object'>,)
>>> print(MyClass.__dict__)
{'__module__': '__main__', '__qualname__': 'MyClass', '__weakref__': <attribute '__weakref__' of 'MyClass' objects>, 'showMyVersion': , '__dict__': <attribute '__dict__' of 'MyClass' objects>, '
myVersion': '1.1', '__doc__': 'MyClass class definition'}
一、classmethod和staticmethod区别
类和实例都是对象.
所以它们可以有方法.
类的方法就叫类方法.
实例的方法就叫实例方法.
至于静态方法就是写在类里的方法,必须用类来调用(极少数情况下使用,一般都在全局里直接写函数了)
class Kls(object):
def __init__(self, data):
self.data = data
def printd(self):
print(self.data)
@staticmethod
def smethod(*arg):
print('Static:', arg)
@classmethod
def cmethod(*arg):
print('Class:', arg)
>>> ik = Kls(23)
>>> ik.printd()
23
>>> ik.smethod()
Static: ()
>>> ik.cmethod()
Class: (<class '__main__.Kls'>,)
>>> Kls.printd()
TypeError: unbound method printd() must be called with Kls instance as first argument (got nothing instead)
>>> Kls.smethod()
Static: ()
>>> Kls.cmethod()
Class: (<class '__main__.Kls'>,)
class Data_test2(object):
day=0
month=0
year=0
def __init__(self,year=0,month=0,day=0):
self.day=day
self.month=month
self.year=year
@classmethod
def get_date(cls,data_as_string):
#这里第一个参数是cls, 表示调用当前的类名
year,month,day=map(int,string_date.split('-'))
date1=cls(year,month,day)
#返回的是一个初始化后的类
return date1
def out_date(self):
print "year :"
print self.year
print "month :"
print self.month
print "day :"
print self.day
在Date_test类里面创建一个成员函数, 前面用了@classmethod装饰。 它的作用就是有点像静态类,比静态类不一样的就是它可以传进来一个当前类作为第一个参数。
r=Data_test2.get_date("2016-8-6")
r.out_date()
输出:
year :
2016
month :
8
day :
1
案例
import os
os.chdir('E:\\py\\chapter6')
def sanitize(time_string):
if '-' in time_string:
splitter='-'
elif ':' in time_string:
splitter=':'
else:
return(time_string)
(mins,secs)=time_string.split(splitter)
return(mins +'.' + secs)
class Athlete:
def __init__(self,a_name,a_dob=None,a_times=[]):
self.name=a_name
self.dob=a_dob
self.times=a_times
def top3(self):
return(sorted(set([sanitize(t) for t in self.times]))[0:3])
def add_time(self,time_value):
self.times.append(time_value)
def add_times(slef,list_of_times):
self.times.extend(list_of_times)
def get_coach_data(filename):
try:
with open(filename) as f:
data=f.readline()
templ=data.strip().split(',')
return(Athlete(templ.pop(0),templ.pop(0),templ))
except IOError as ioerr:
print('File error:' +str(ioerr))
return(None)
sarah=get_coach_data('sarah2.txt')
print(sarah.name+"'s fastest times are:"+str(sarah.top3()))
也可调用内置的类,建立类的父子关系
import os
os.chdir('E:\\py\\chapter6')
def sanitize(time_string):
if '-' in time_string:
splitter='-'
elif ':' in time_string:
splitter=':'
else:
return(time_string)
(mins,secs)=time_string.split(splitter)
return(mins +'.' + secs)
class Athlete(list):
def __init__(self,a_name,a_dob=None,a_times=[]):
list.__init__([])
self.name=a_name
self.dob=a_dob
self.extend(a_times)
def top3(self):
return(sorted(set([sanitize(t) for t in self]))[0:3])
def get_coach_data(filename):
try:
with open(filename) as f:
data=f.readline()
templ=data.strip().split(',')
return(Athlete(templ.pop(0),templ.pop(0),templ))
except IOError as ioerr:
print('File error:' +str(ioerr))
return(None)
sarah=get_coach_data('sarah2.txt')
print(sarah.name+"'s fastest times are:"+str(sarah.top3()))
参考资料
这里是一个广告位,,感兴趣的都可以发邮件聊聊:tiehan@sina.cn
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn
个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn