【必赢亚洲mg娱乐在线】面向对象,面向对象之

作者:计算机知识

 

1  class student
 2     {
 3         public int _code;
 4         public int Code//属性
 5         {
 6             //获取值
 7             get
 8             {
 9                 return 5;
10             }
11             //设置值
12             set
13             {
14                 _code = value   9;
15             }
16         }
17         private string _name;
18         public string Name
19         {
20             get { return _name; }
21             set { _name = value; }
22         }   
23     }
24 
25 student s = new student();
26             s.Code = 3;
27             Console.WriteLine(s.Code);
28             Console.WriteLine(s._code);
29             Console.ReadLine();
1  class student
 2     {
 3         public int _code;
 4         public int Code//属性
 5         {
 6             //获取值
 7             get
 8             {
 9                 return 5;
10             }
11             //设置值
12             set
13             {
14                 _code = value   9;
15             }
16         }
17         private string _name;
18         public string Name
19         {
20             get { return _name; }
21             set { _name = value; }
22         }   
23     }
24 
25 student s = new student();
26             s.Code = 3;
27             Console.WriteLine(s.Code);
28             Console.WriteLine(s._code);
29             Console.ReadLine();

面向对象——封装

在线编制程序
在线预览:http://github.lesschina.com/python/base/oop/1.封装.html

一、概述

这一次尽量用故事情势来讲知识,上次刚说美化,本次终于第壹篇了。步入正题:

Python面向对象的3大特征:封装、继承和多态。

1.概念二个类必赢亚洲mg娱乐在线,¶

类的组合:类名、属性(未有字段)、方法

卷入:在类中对数据的赋值、内部调用对表面用户是透明的,类就像三个胶囊或容器,里面含有类的数目和章程。

一.一创制二个类¶

In [1]:

# 类名首字母大写
class Student(object):
    """创建一个学生类"""
    # 没有属性定义,直接使用即可
    # 定义一个方法,方法里面必须有self(相当于C#的this)
    def show(self):
        print("name:%s age:%d"%(self.name,self.age))

In [2]:

# 实例化一个张三
zhangsan=Student()
# 给name,age属性赋值
zhangsan.name="张三"
zhangsan.age=22
# 调用show方法
zhangsan.show()

 

name:张三 age:22

In [3]:

# 打印一下类和类的实例
print(Student)
print(zhangsan) #张三实例的内存地址:0x7fb6e8502d30

 

<class '__main__.Student'>
<__main__.Student object at 0x7fe961195b70>

 

和静态语言不相同,Python允许对实例变量绑定任何数据 ==> 对于八个实例变量,虽说它们都以同多个类的不等实例,但装有的变量名称只怕都分化

说的可比抽象,举个例证就明知道:

In [4]:

xiaoming=Student("小明",22)
xiaoming.mmd="mmd"
print(xiaoming.mmd)

# 小明和小潘都是Student类,但是小明有的mmd属性,小潘却没有
xiaopan=Student("小潘",22)
print(xiaopan.mmd)

 

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-500940527165> in <module>()
----> 1xiaoming=Student("小明",22)
      2 xiaoming.mmd="mmd"
      3 print(xiaoming.mmd)
      4 
      5 # 小明和小潘都是Student类,但是小明有的mmd属性,小潘却没有

TypeError: object() takes no parameters

 

二、封装

1.2使用__init__起初化赋值¶

创造对象后,python解释器暗中认可调用__init__情势,对供给字段进行开首化赋值

内需留意的是:__init__并不是C#中的构造函数,__new__ (前边会说) __init__ 等价于构造函数

首先个参数和类的别样措施壹致,都以self(也正是C#在那之中的this,表示创设的实例本身)调用的时候平素忽略它

In [5]:

class Student(object):
    # 初始化赋值
    def __init__(self,name,age):
        self.name=name
        self.age=age

    def show(self):
        print("name:%s age:%d"%(self.name,self.age))

In [6]:

# 有了__init__方法,在创建实例的时候,就不能传入空的参数了
lisi=Student()

 

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-1ba88e24910b> in <module>()
      1 # 有了__init__方法,在创建实例的时候,就不能传入空的参数了
----> 2lisi=Student()

TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'

In [7]:

# 创建一个正确的实例
xiaowang=Student("小王",22)
xiaowang.show()

【必赢亚洲mg娱乐在线】面向对象,面向对象之。 

name:小王 age:22

 

在类中大家封装什么?属性、方法和对象

壹.三采纳法力方法__str__¶

在print(类名)的时候自定义输出

以此有一些像C#类里面重写ToString,eg:

public override string ToString()
{
    return "Name:"   this.Name   " Age:"   this.Age;
}

In [8]:

# Python的__str__()方法
class Student(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # self别忘记写了,return也别忘了
    def __str__(self):
        return "姓名:%s,年龄:%s" % (self.name, self.age)

In [9]:

lisi = Student("李四", 22)
print(lisi) #现在打印就是你DIV的输出了

 

姓名:李四,年龄:22

 

包装,看名就能够知道意思正是将内容封装到有些地方,未来再去调用被封装在某处的内容。所以,在利用面向对象的封装性子时,要求:

一.四 私有属性、方法¶

C#、Java里面都是有访问修饰符的,Python呢?

Python规定,如果以双下划线__开头的属性也许措施不畏个人的

变量名类似xxx的,也正是以双下划线伊始,并且以双下划线结尾的,是优异变量。特殊变量是能够直接待上访问的,不是private变量

在说私有属性前,我们来个案例说说属性不私有的弊端,eg:

小明同学学了点C#,然后学习了地方的文化,心想 ~ Python这么搞安全性呢?不行,作者得协会构造,于是有了下边包车型大巴代码:

In [10]:

class Student(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def get_name(self):
        return self.name

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

    def get_age(self):
        return self.age

    def set_age(self, age):
        if age > 0:
            self.age = age
        else:
            print("age must > 0")

    def show(self):
        print("name:%s,age:%d" % (self.name, self.age))

 

小明心想,想要修改age属性,你通过set_age作者就能够看清了哇,照旧本婴孩聪明

此刻小潘过来了,淡淡的1笑,看本人怎么破了你 ~ 看代码:

In [11]:

zhangsan = Student("张三", -20)
zhangsan.show()  # name:张三,age:-20
zhangsan.age = -1  # set_age方法形同虚设,我完全可以直接访问字段了
zhangsan.show()  # name:张三,age:-1

 

name:张三,age:-20
name:张三,age:-1

 

小潘傲气的说道~三伯,给你脸吗。笔者正是不去做客你设定的主意怎么滴呢?

小明急的呀,赶紧去找伟哥求经。不1会,傲气的贴出本人的New Code,心想着自己个人属性都用上了还怕个毛毛:

In [12]:

class Student(object):
    def __init__(self, name, age):
        self.__name = name
        # 一般需要用到的属性都直接放在__init__里面了
        # self.__age = age
        self.set_age(age)

    def get_name(self):
        return self.__name

    def set_name(self, name):
        self.__name = name

    def get_age(self):
        return self.__age

    def set_age(self, age):
        if age > 0:
            self.__age = age
        else:
            print("age must > 0")

    def show(self):
        print("name:%s,age:%s" % (self.__name, self.__age))

 

小潘冷笑道~呵呵,然后使用了上次的高招:

In [13]:

zhangsan = Student("张三", -20)
zhangsan.__age = -1  # 同样的代码,只是属性前面加了下划线
zhangsan.show()

 

age must > 0

 

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-13-82c41ff46846> in <module>()
      1 zhangsan = Student("张三", -20)
      2 zhangsan.__age = -1  # 同样的代码,只是属性前面加了下划线
----> 3zhangsan.show()

<ipython-input-12-1dec32486a19> in show(self)
     22 
     23     def show(self):
---> 24print("name:%s,age:%s" % (self.__name, self.__age))

AttributeError: 'Student' object has no attribute '_Student__age'

 

这一次小潘同志傻眼了,完全不可能访问了啊?不行,怎么能被小明岳父笑话吗?

于是上网翻资料,国内极度就外国,外文不佳就翻译,终于找到三个新破解格局:

双下划线早先的实例变量不能够一向访问,是因为Python解释器对外把__age变量改成了_Studentage,所以,仍旧能够通过**_Studentage**来访问:

In [14]:

# 搞事情
zhangsan._Student__age = -1
zhangsan.show()

 

name:张三,age:-1

 

建议你绝不那样干,不相同版本的Python解释器可能会把__age改成区别的变量名

稍稍时候,你相会到以三个下划线开首的实例变量名,比如_age那样的实例变量,外部是足以访问的。

但是,请把它视为私有变量,不要随意走访(Python多数东西全凭自觉~捂脸@_@)

小潘终于长叹一口气,然后还不忘嘲笑小明同学~您这属性搞的,真费劲,总是通过措施调用,太累了 <_> 鄙视!

那可把小明急的呦,学习的积极都没有了,吃了碗羖肉面就去伟哥那边好好取经了~

In [15]:

# 私有方法一笔带过
class Student(object):
    """私有方法"""
    def __go_home(self):
        pass


zhangsan = Student()
zhangsan.__go_home() # 访问不到

 

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-15-45c76191b808> in <module>()
      7 
      8 zhangsan = Student()
----> 9zhangsan.__go_home() # 访问不到

AttributeError: 'Student' object has no attribute '__go_home'

 

·将内容封装到某处

1.5 装饰器,让艺术像属性那样便利¶

Python内置的@property装饰器正是肩负把二个主意成为属性调用的,来个例证

In [16]:

class Student(object):
    def __init__(self, name, age):
        # 一般需要用到的属性都直接放在__init__里面了
        self.name = name
        self.age = age

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, age):
        if age > 0:
            self.__age = age
        else:
            print("age must > 0")

    def show(self):
        print("name:%s,age:%s" % (self.name, self.age))

In [17]:

xiaoming = Student("小明", 22)
xiaoming.name = "小潘"
xiaoming.age = -2
xiaoming.show()

 

age must > 0
name:小潘,age:22

 

把一个getter方式成为属性,只需求加上@property就能够了

@方法名.setter,肩负把三个setter方法变成个性赋值

理当如此了,假如只想读 ==> 就只打上@property标签

小明同学喜欢坏了,赶紧大吃了一顿~


·从某处调用被打包的原委

1.6 __del__ and __new__¶

创造对象后,python解释器默许调用__init__() 方法

当删除1个对象时,python解释器也会暗中同意调用__del__() 方法(有一点析构函数的暗意)

当有3个变量保存了对象的引用时,此目的的引用计数就能加一

当使用del删除变量指向的指标时,比如指标的引用计数不为壹,那么老是删除计数减1,当计数为一的时候再调del就真把目的删了

其1能够整合本人以前说过的链接来驾驭:于链接文件的研商

瞧着教授两道三科,小明愣了楞,摸摸肚子想到,真BB,我先搞个例子练练:

In [1]:

# 定义一个临时类
class Temp(object):
    def __del__(self):
        print("你被干掉了")

 

证实方面用编辑器比较确切,交互格局下大概不是真的的结果

# 对象被s1和s2引用
s1 = Temp()
s2 = s1

del s1  # 只删除s1,新创建的对象并没有被删除
print("-" * 10)

输出:(最终的被干掉是先后退出了)

# ----------
# 你被干掉了

假若用链接来分解正是这么的: 必赢亚洲mg娱乐在线 1

此番三个都删掉:

t1 = Temp()
t2 = t1

del t1
del t2
print("-" * 10)

输出:

# 你被干掉了
# ----------

都删了,自然就真删掉了


那般搞比较费心,大家引进一下获得引用个数:getrefcount(object也会占一个引用计数)来个案例:

# 程序退出的时候,在他运行期间所有占用资源归还操作系统
# 引用计数
import sys
t1 = Temp()
print(sys.getrefcount(t1))  #(结果比实际引用大1)【object也会占1个引用计数】

t2 = t1
print(sys.getrefcount(t1))
print(sys.getrefcount(t2))

del t1
print(sys.getrefcount(t2))
# sys.getrefcount(t1)#被删掉自然没有了

del t2
print("-" * 10)

运行结果:

2
3
3
2
你被干掉了
----------

自己再贴壹种意况,你能够思考下为什么:

t1 = Temp()
t2 = Temp()

del t1
del t2
print("-" * 10)

输出:

# 你被干掉了
# 你被干掉了
# ----------

 


小潘扭过头瞅了一眼说道:“四伯,你__new__忘掉写案例了”

小美赞臣(Meadjohnson)愣神,立马反应过来讲:“小编那叫谋而后动~”

当您实例化二个目的的时候,就能够施行new 方法里面包车型客车法子。new方法在类定义中不是必须写的,要是没概念,暗许会调用object.new去创制三个对象

__new__主意中至少要有1个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供

__new__主意中必供给有再次来到值(重返实例化出来的实例)

小明翻阅了官方文书档案,淡定的抢占了如下规范格式的代码:

In [3]:

class Dog(object):
    def __init__(self, name):
        self.name = name
        print("初始化完毕")

    def __str__(self):
        return "Dog的名字叫:%s" % self.name

    def __new__(cls, name):
        # 注意参数,是cls,然后其他参数和init保持一致即可
        print("创建对象完毕")
        # 别忘记写返回值哦
        return object.__new__(cls)


def main():
    happy = Dog("Happy")
    print(happy)


if __name__ == '__main__':
    main()

 

创建对象完毕
初始化完毕
Dog的名字叫:Happy

 


关于__name__在模块调用的时候会详细说,你能够先这么敞亮:假使一直运转py文件就实行,外人调用那么你的main就不试行了

行业内部写法:

# 1.导入的模块
# 2.class的定义
# 3.其他方法定义

def main():
    pass

if __name__ == '__main__':
    main()

此外剧情后边会三番五次说,封装部分再说说静态方法类方法等等的就甘休了(和C#要么有不小分其余)


率先步:将内容封装到某处

一.柒 类属性、实例属性¶

小明问老师:“老师老师,怎么没有静态类,静态属性之类的东西啊?”

师资笑而不语道:“小兄弟原来不仅是体重扩大啊,那求知欲也是大大的扩充呢 ~ 且听本人逐步道来”


类在先后里面也是指标(你姑且能够认为具有的类都就如于C#中间的静态类),而通过类实例化的目的,叫实例化对象

实例属性 --> 实例对象相互之间不共享 一般我们都是在__init__中定义

类属性(类似于C#里头的静态字段) --> 属于类对象,多少个实例对象时期共享

注意一下:同样名称的实例属性将屏蔽掉类属性(尽量别同名)

类属性除了能够透过 类名.类属性 访问外,仍是可以直接 实例对象.类属性 (C#中抽象类和静态类是不可能被实例化的)

来个案例越来越直观点:

In [1]:

class Person(object):
    # age为类属性
    age = 1

    def __init__(self, name):
        # name为实例属性
        self.name = name


def main():
    # 类名.类属性
    print(Person.age)
    xiaoming = Person("小明")
    # 对象.类属性
    print(xiaoming.age)


if __name__ == '__main__':
    main()

 

1
1

 


若是需求在类外 修改类属性,必须透过类对象去引用然后开始展览修改

只要经过实例对象去引用会产生二个同名的实例属性,这种艺术修改的是实例属性,不会潜移默化到类属性

假定由此实例对象去引用该名称的特性,实例属性会强制 屏蔽掉类属性,即引用的是实例属性,除非del了该实例属性本领平常访问类属性

你能够通晓为,Python这么做只是为了便利你拿走,该怎么修改还得如何做。来看个案例:

In [3]:

class Person(object):
    # age为类属性
    age = 1

    def __init__(self, name):
        # name为实例属性
        self.name = name


def main():
    # 类名.类属性
    print(Person.age)

    # 通过对象.类属性修改
    xiaoming = Person("小明")
    xiaoming.age = 100
    print(xiaoming.age)  # 其实,并没有修改成功,只是产生了一个同名age
    print(Person.age)  # 对吧,类属性并没有被修改

    # 通过类名修改
    Person.age = 22  # 如果需要在类外修改类属性,必须通过类对象去引用然后进行修改
    print(xiaoming.age)  # 刚才已经创建一个同名age,所以现在显示的是刚才的值
    print(Person.age)  # 通过类名.类属性 就可以看到值被修改了

    # 如果你还是不信,可以创建一个新对象看看
    xiaopan = Person("小潘")
    print(xiaopan.age)

    # xiaoming实例对象想访问怎么办?
    # 除非del了该实例属性才能正常访问类属性
    del xiaoming.age
    print(xiaoming.age)  # 这时候访问的就是 类属性 了


if __name__ == '__main__':
    main()

 

1
100
1
100
22
22
22

 

self是贰个试样参数,当试行obj一 = Foo('wupeiqi', 18)时,self等于obj一当施行obj二 =Foo('alex', 7捌 )时,self等于obj贰

本文由bwin必赢发布,转载请注明来源

关键词: 日记本 亚洲必赢766net .NET技术 Visual Studi