面向对象编程

类与实例:

说明:没有提供方法或属性的类,将类作为名称空间容器。

class MyData():
    '''定义一个新式类,必须继承至少一个父类,默认的父类为object'''
    pass

class MyData:
     '''定义一个j经典类'''    
    pass
View Code

方法:给类添加功能,在类中定义,只能被实例调用。

在定义方法时存在self默认参数,它代表实例对象本身,不需要给self传递参数。

__init__():类构造器,在实例化过程中,调用__init__()方法,作用:可以设置初始值或者运行一些初步的诊断代码。

创建子类:子类继承父类的所有特性,通常与类无区别,也需要进行实例化。每个子类最好定义自己的构造器,否则会调用父类的构造器,如果子类重写父类的构造器,则父类的构造器将不会自动调用,此时,父类的构造器需要显示写出才会被执行。

class Fruit():
    '''
    定义一个父类,类名称为水果,其中包括水果的属性以及方法
    '''
    def __init__(self,name,color,shape):
        self.name = name
        self.color = color
        self.shape = shape
        print('%s\'s color is %s' % (self.name,self.color))
        print('%s\'s shape is %s' % (self.name,self.shape))
    def updateColor(self,newcl):
        self.newcl = newcl
        print('%s\'s newcolor is %s' % (self.name,self.newcl))
class WaterFruit(Fruit):
    '''
    定义一个子类,类名称为WaterFruit
    '''
    def __init__(self,name,color,shape,taste):
        Fruit.__init__(self,name,color,shape)
        self.taste = taste
        print('%s\'s taste is %s' % (self.name,self.taste))
    def updateTaste(self,newts):
        self.newts = newts
        print('%s\'s newtaste is %s' % (self.name,self.newts))
apple = Fruit('apple','green','round')
apple.updateColor('red')
banana = Fruit('banana','green','strip')
banana.updateColor('yellow')
watermelon = WaterFruit('watermelon','green','round','tasteless')
watermelon.updateTaste('sweet')

>>> 
apple's color is green
apple's shape is round
apple's newcolor is red
banana's color is green
banana's shape is strip
banana's newcolor is yellow
watermelon's color is green
watermelon's shape is round
watermelon's taste is tasteless
watermelon's newtaste is sweet
>>> 
View Code

类属性:

类的数据属性:静态变量或静态数据。通常用来跟踪与类相关的值。

class C(object):
    a = 100
print(C.a)
>>> 
100
>>> 
View Code

方法:必须绑定到一个实例,才能被调用。方法都是它所在类的固有属性。

class Talk(object):
    def SiHi(self):
        print("hello,world")
c = Talk()
c.SiHi()
SiHi()
>>> 
hello,world
Traceback (most recent call last):
  File "C:\Users\七彩蜗牛\Desktop\test.py", line 6, in <module>
    SiHi()
NameError: name 'SiHi' is not defined
>>> 
View Code

查看类的属性:

dir()  :返回对象的属性的一个名字列表

__dict__:返回一个字典,键是属性名,键值是相应的属性对象的数据值。查看类或对象的属性。

C.__name__ :类C的名字

C.__doc__:类C的文档字符串

C.__bases__:类C的所有父类构成的元组

C.__dict__:类C的属性

C.__module__:类C定义所在的模块

C.__class__:实例C对应的类

>>> dir(Talk)
['SiHi', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> Talk.__dict__
mappingproxy({'SiHi': <function Talk.SiHi at 0x029456F0>, '__module__': '__main__', '__doc__': None, '__weakref__': <attribute '__weakref__' of 'Talk' objects>, '__dict__': <attribute '__dict__' of 'Talk' objects>})
>>> 
>>> print(Talk.__doc__)
None
>>> print(Talk.__module__)
__main__
>>> print(Talk.__name__)
Talk
>>> print(Talk.__bases__)
(<class 'object'>,)
>>> print(Talk.__class__)
<class 'type'>
>>> print(c.__class__)
<class '__main__.Talk'> #自定义模块名为__main__ 类的全名为__main__.Talk
View Code

 type():返回调用对象的类型

class A():
    pass
a = A()
class B:
    pass
b = B()
>>> type(A)
<class 'type'>
>>> type(B)
<class 'type'>
>>> type(a)
<class '__main__.A'>
>>> type(b)
<class '__main__.B'>
>>> 
View Code

__init__():构造器方法。实例化的第一步是创建实例对象,对象创建后,将检查是否实现__init__()方法。此方法用来实现特定的操作。若有此方法,则将被调用。

实例对象作为第一个参数(self)被传递进去。调用类时,传进的任何参数都交给__init__(),即创建实例的调用即是对构造器的调用。

__new__():对内建类型进行派生,用来实例化不可变对象

__del__():解构器方法。

class InstCt(object):
    count = 0
    def __init__(self):
        InstCt.count += 1
    def __del__(self):
        InstCt.count -= 1
    def howMany(self):
        return InstCt.count
>>> a = InstCt()
>>> b = InstCt()
>>> print(id(a),id(b))
49972464 52235440
>>> a.howMany()
2
>>> b.howMany()
2
>>> del a
>>> a.howMany()
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    a.howMany()
NameError: name 'a' is not defined
>>> b.howMany()
1
>>> del b
>>> InstCt.count
0
>>> 
View Code

__init__():返回值为None, 也应当返回None,不应该返回任何对象,因为实例对象是自动在实例化调用后返回的,即只能返回实例。返回非None的任何其他对象都会导致异常

class Init(object):
    count = 0
    def __init__(self):
        print('init')
        return 1
>>> a = Init()
init
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    a = Init()
TypeError: __init__() should return None, not 'int'
>>> 
View Code

建类型属性

a = 'hello'
>>> type(a)
<class 'str'>
>>> type.__class__
<class 'type'>
>>> a.__class__
<class 'str'>
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
>>> a.__dict__
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    a.__dict__
AttributeError: 'str' object has no attribute '__dict__'
>>> a.__len__
<method-wrapper '__len__' of str object at 0x0332B980>
>>> a.endswith('o')
True
>>> a.__doc__
"str(object='') -> str\nstr(bytes_or_buffer[, encoding[, errors]]) -> str\n\nCreate a new string object from the given object. If encoding or\nerrors is specified, then the object must expose a data buffer\nthat will be decoded using the given encoding and error handler.\nOtherwise, returns the result of object.__str__() (if defined)\nor repr(object).\nencoding defaults to sys.getdefaultencoding().\nerrors defaults to 'strict'."
>>> 
View Code

实例属性和类属性:

类属性可通过类或实例来访问:

>>> class C(object):
    version = 1.2 #静态成员:类属性

>>> c = C()
>>> c.version
1.2
>>> C.version
1.2
>>> C.version += 1 #只能通过类来更新静态成员
>>> C.version
2.2
>>> c.version
2.2
>>> c.version -= 1 #创建了自身的一个属性version,不会再去调用类中的静态成员,说明:任何对实例属性的赋值都会创建一个实例属性(如果不存在)同时对其赋值。
>>> C.version
2.2
>>> c.version
1.2000000000000002
>>> C.version
2.2
>>> del c.version #删除自身的属性version后,再次访问将调用类中的静态成员
>>> c.version
2.2
>>> C.version
2.2
>>> c.version = 3
>>> c.__dict__
{'version': 3}
>>>
View Code

 类属性为可变成员,对实例属性的赋值将不会创建实例属性,而是直接对类属性进行更新。

>>> class Foo():
    a = [1,2,3,4]

>>> foo = Foo()
>>> foo.a
[1, 2, 3, 4]
>>> foo.a[2] = 5
>>> foo.a
[1, 2, 5, 4]
>>> Foo.a
[1, 2, 5, 4]
>>> foo.__dict__
{}
>>> Foo.__dict__
mappingproxy({'__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__module__': '__main__', '__doc__': None, '__dict__': <attribute '__dict__' of 'Foo' objects>, 'a': [1, 2, 5, 4]})
>>> del foo.a
Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    del foo.a
AttributeError: a
>>> 
View Code

 绑定和方法调用:方法属于类属性,通过实例调用即只有存在实例时,方法才被认为是绑定到那个实例了。无实例时方法是未绑定的。

方法中的默认参数self,表示调用此方法的实例对象,即self用来代表实例。

调用绑定方法:通过实例调用绑定在实例上的方法,在实际调用时不需要传入self的参数,self作为第一个参数被默认传入。

>>> class SaySomething():
    def __init__(self,sayWord = 'hello,world!'):
        self.sayWord = sayWord
    def say(self):
        print(self.sayWord)
>>> say1 = SaySomething()
# 通过实例调用绑定的方法:
>>> say1.say()
hello,world!
# 通过类调用绑定的方法时会报错:
>>> SaySomething.say()
Traceback (most recent call last):
  File "<pyshell#150>", line 1, in <module>
    SaySomething.say()
TypeError: say() missing 1 required positional argument: 'self'
>>>
View Code

调用非绑定方法:通过类来调用方法,调用时必须显示的传入self参数,解释器才能知道需要初始化的是一个类而不是绑定在类上的实例。

class WaterFruit(Fruit):
    def __init__(self,name,color,shape,taste):
        Fruit.__init__(self,name,color,shape) #调用非绑定方法,通过父类绑定方法
        self.taste = taste
        print('%s\'s taste is %s' % (self.name,self.taste))
View Code

静态方法和类方法:

方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self

类方法:由调用; 至少一个cls参数;执行类方法时,自动将调用该方法的复制给cls

静态方法:由调用;无默认参数;

class Foo:

    def __init__(self, name):
        self.name = name

    def ord_func(self):
        """ 定义普通方法,至少有一个self参数 """
        print('普通方法')

    @classmethod
    def class_func(cls):
        """ 定义类方法,至少有一个cls参数 """
        print('类方法')
    
    @staticmethod
    def static_func():
        """ 定义静态方法 ,无默认参数"""
        print ('静态方法')


# 调用普通方法
f = Foo('zyj')
f.ord_func()

# 调用类方法
c = Foo('zyj')
Foo.class_func()
c.class_func()

# 调用静态方法
s = Foo('zyj')
s.static_func()
Foo.static_func()
View Code

 

posted @ 2016-03-31 23:11  七彩蜗牛  阅读(252)  评论(0)    收藏  举报